DOCS
How Libregochi works under the pixels: payments, the contract, the rules and the resources it uses on Libre. Written for builders, block producers and anyone who wants to check our work.
The numbers and graphs on this page are generated from the code the game runs, so they change when the rules do.
At a glance
- A cozy 32×32 pixel pet game on Libre (Antelope/Leap 5). Pets never die; neglected ones get sick and recover with care.
- Players design their pet in a creator (8 bodies, 16 palettes, 12 eyes, 10 patterns). Nothing is rolled.
- Care is free: every feed, play, clean and nap is a transaction with 0 fees.
- Items have fixed prices in LIBRE or BTC, shown before paying. No token of our own, no staking, no farming.
- Pets, items, stats and XP live in the
libregochicontract. There is no game server; the chain is the database.
Architecture
libregochi.com is a static Next.js export on Cloudflare. The browser reads the contract's tables straight from Libre nodes, with failover between endpoints, and the keeper's wallet signs every action. A small Worker handles only /api/* (the waitlist). Each build is fixed to one network, so nobody signs on the wrong chain.
SHOW THE NUMBERS
| Part | What it does |
|---|---|
| libregochi.com | Static site on Cloudflare; a Worker only for /api/* |
| Browser | Draws the pet and computes live stats with the same rules as the contract |
| Wallet | WharfKit: Bitcoin Libre or Anchor; signs each action |
| Libre nodes | get_table_rows reads, 3 mainnet endpoints with failover |
| libregochi | Holds pets, items, players; runs the rules |
The rules live in one TypeScript package with integer math only. The C++ contract implements the same rules, and both run the same shared test vectors, so the stats the page shows are the stats the chain stores.
Networks and accounts
| Network | Chain ID | Endpoints |
|---|---|---|
| Libre Mainnet | 38b1d7815474d0c60683ecbea321d723e83f5da6ae5f1c1f9fecc69d9ba96465 | https://lb.libre.org https://api.libre.cryptobloks.io https://libre.greymass.com |
| Libre Testnet | b64646740308df2ee06c6b72f34c0f7fa066d940e831f752db2006fcc2b78dee | https://testnet.libre.org https://api.testnet.libre.cryptobloks.io https://libretestnet.greymass.com |
libregochi: the game contract. Every purchase is a transfer to it.gochivault: receives 70% of LIBRE and 90% of BTC payments. It is the studio's account: it pays for running and building the game, the developer's pay included.eosio.null: burned LIBRE goes here. Nobody holds its keys.- Status: the contract goes to testnet first, once the board grants it resources; mainnet follows a testnet play-test and a security review. Progress is on the roadmap.
Paying
Every purchase is a plain token transfer to libregochi with a memo. The Bitcoin Libre wallet shows only from, to, quantity and memo when it asks to sign, so that is everything a purchase needs. The contract reacts to the transfer notification and splits the payment on the spot; it keeps nothing.
LIBRE
BTC
SHOW THE NUMBERS
| Token | Vault | Burned | Referrer |
|---|---|---|---|
| LIBRE | 70% | 20% | 10% |
| BTC | 90% | 0% | 10% |
MEMOS
adopt:<name>;l=<look>[;r=<referrer>] an egg designed as <look> buy:<templateId>[;r=<referrer>] a wearable, into the inventory buy:<templateId>:<petId>[;r=<referrer>] food, care or a helper, used on a pet rename:<petId>:<name> a new name
| adopt:Mochi;l=3.12.7.4.g | adopt an egg named Mochi, designed as body 3, palette 12, eyes 7, pattern 4, a girl |
| buy:14;r=alice | buy item 14 (a wearable) into the inventory; alice invited this keeper |
| buy:9:42 | buy item 9 (food, care or a helper) and use it on pet 42 right away |
| rename:42:Sir Mochi | rename pet 42 |
The template and pet ids above are examples.
- Only
eosio.tokenLIBRE (4 decimals) andbtc.libreBTC (8 decimals) are accepted, checked by the notification's first receiver, so a look-alike token is refused. - The quantity must be exactly the price in the templates table. Anything else is refused and the whole transfer reverts.
r=<referrer>is bound once: the first purchase that names a referrer sets it, and it never changes after that. Nobody can invite themselves. The referrer's share goes to the vault when the referrer has no balance row for that token, because creating one would cost the contract RAM.- The read-only
checkmemoaction says what a memo means, or why it would be refused, so wallets and tools can check one before signing. The web app builds memos with the same grammar the contract parses. - The starter egg is free:
claimstarter, once per keeper, soulbound, for accounts that hold at least 1,000 LIBRE or 1,000 sats, which keeps throwaway accounts from farming eggs.
Prices
Prices are set in US dollars and stored in the contract's templates table as fixed LIBRE and sats amounts. They are checked on the 1st of each month and repriced only when a rate has moved more than 25%, announced a week ahead. Between repricings, the price in LIBRE and sats doesn't move.
The LIBRE rate comes from the swap.libre BTC/LIBRE pool (BLLP) times BTC/USD, as a 7-day median. The on-chain oracle and the price trackers lag behind for LIBRE, so we don't use them.
SHOW THE NUMBERS
| Item | Kind | USD |
|---|---|---|
| Kibble bowl | food | 1¢ |
| Cookie | food | 2¢ |
| Rice ball | food | 2¢ |
| Soap | care | 2¢ |
| Strawberry | food | 3¢ |
| Pizza | food | 5¢ |
| Toy ball | care | 5¢ |
| Comfy Pillow | helper | 10¢ |
| Medicine | care | 10¢ |
| XP Snack | helper | 10¢ |
| Warm Blanket | helper | 25¢ |
| Party hat | wearable | 30¢ |
| Round glasses | wearable | 30¢ |
| Cozy scarf | wearable | 40¢ |
| Flower crown | wearable | 40¢ |
| Star shades | wearable | 50¢ |
| Witch hat | wearable | 50¢ |
| Raincoat | wearable | 60¢ |
| Tiny wings | wearable | $1.00 |
| Extra egg | pet | $1.50 |
The contract
One contract, libregochi. Every action that changes state calls require_auth on the account it acts for. Purchases aren't actions: the contract reacts to transfers sent to it. It accepts only eosio.token / btc.libre::transfer; any other token is refused, so that transfer fails.
CARE (THE KEEPER SIGNS; FREE)
setoffset(keeper: name, minutes: int16)
Sets the keeper's local day for routines, daily caps and the streak. Once only; the web app sends it with the first care action. Signed by: keeper.
feed(keeper: name, pet_id: uint64)
A free bowl (+30 hunger), 3 per pet per local day. More food is bought. Signed by: keeper.
play(keeper: name, pet_id: uint64)
+20 happiness, −10 energy; once an hour. Signed by: keeper.
clean(keeper: name, pet_id: uint64)
Hygiene back to 100; every 2 hours. Signed by: keeper.
sleep(keeper: name, pet_id: uint64)
A nap: energy comes back at 25 an hour until it's full, and the pet wakes on its own. Signed by: keeper.
pet(keeper: name, pet_id: uint64, taps: uint16)
Petting from the browser, synced at most every 4 hours. Adds happiness and a little capped XP; not a care action for the streak. Signed by: keeper.
minigame(keeper: name, pet_id: uint64, game: uint8, score: uint32)
A finished skill game. XP is capped per play and per day, so a made-up score gains nothing extra. Signed by: keeper.
STARTER EGG
claimstarter(keeper: name, pet_name: string, look: string)
The free starter egg: one per keeper, soulbound, a daily cap for everyone together, and a little LIBRE or BTC in the account. Signed by: keeper.
WEARABLES AND GIFTS
equip(keeper: name, pet_id: uint64, item_id: uint64)
Puts a wearable on a pet; whatever was in that slot goes back to the inventory. Signed by: keeper.
unequip(keeper: name, item_id: uint64)
Takes a wearable off. Signed by: keeper.
gift(from: name, to: name, pet_ids: uint64[], item_ids: uint64[], memo: string)
Gives pets and items to another keeper for free. Soulbound ones can't be given; a pet keeps what it wears, except soulbound items. Signed by: from.
READ-ONLY
checkmemo(memo: string)
Returns what a memo means, or why it would be refused. Wallets and tools can check a memo with it before signing. Signed by: none (read-only).
ADMIN (ON MAINNET, SIGNING REQUESTS THE OWNER SIGNS)
setconfig(vault: name, hatch_delay_sec: uint32, starters_per_day: uint32, bodies: uint8, palettes: uint8, eyes: uint8)
Game settings. On mainnet every admin action is a signing request the owner signs. Signed by: libregochi.
settemplate(tpl: template_row)
Adds or reprices a shop item. An item's kind and slot never change, and `sold` is counted by the contract. Signed by: libregochi.
pause(paused: bool)
Stops or resumes purchases, starter eggs, care, equipping and gifts, for incidents. The contract starts paused. Signed by: libregochi.
TABLES
Every table is in scope libregochi. Rows have a bounded size: names are at most 16 characters, and daily counters are keyed by day number and overwritten, never appended to.
config key singleton
Game settings.
7 FIELDS
paused bool vault name receives the vault share hatch_delay_sec uint32 starters_per_day uint32 free starter eggs, all keepers together bodies uint8 creator option counts palettes uint8 eyes uint8 state key singleton
Counters for new ids, which are never reused.
4 FIELDS
next_pet_id uint64 next_item_id uint64 starter_day uint32 UTC day number of the counter below starters_today uint32 templates key id
Everything the shop sells, at fixed prices in both currencies.
16 FIELDS
id uint64 1 = egg, 2 = rename key string catalog key, e.g. xp-snack kind uint8 1 food, 2 care, 3 helper, 4 streak, 5 egg, 6 wearable, 7 service slot uint8 wearables: 1 head, 2 face, 3 body, 4 back min_level uint8 price_libre int64 LIBRE units, 4 decimals price_sats int64 BTC units, 8 decimals hunger int8 stat effects when used, −100..100 happiness int8 energy int8 hygiene int8 xp uint16 max_supply uint32 0 = unlimited sold uint32 on_sale bool special uint8 0 none, 1 medicine, 2 XP Snack, 3 Comfy Pillow, 4 Warm Blanket players key account
One row per keeper.
15 FIELDS
account name referrer name bound once; empty = none utc_offset_min int16 offset_set bool starter_claimed bool joined uint32 streak_days uint16 streak_last_day uint32 local day number freezes uint8 broken_day uint32 days_before uint16 the streak before a break, for repair pets_owned uint16 at most 30 items_owned uint16 at most 300 care_day uint32 care_today uint8 care actions toward today's streak day pets key id · index byowner (owner)
One row per pet, fixed size. Stats are stored at last_update and decay is computed when read or acted on.
47 FIELDS
id uint64 owner name name_text string body uint8 the look, chosen by the keeper palette uint8 eyes uint8 pattern uint8 gender uint8 0 boy, 1 girl gen uint16 tradable bool false for the starter created uint32 hatch_at uint32 hunger uint8 0–100 at last_update happiness uint8 energy uint8 hygiene uint8 last_update uint32 asleep_until uint32 neglect_since uint32 0 = cared for sick_since uint32 0 = healthy good_since uint32 start of the current run of good care xp uint32 xp_day uint32 local day of the counters below xp_care uint8 today's XP per capped source xp_routine uint8 xp_minigame uint8 xp_petting uint8 xp_healthy uint8 plays_today uint8 bowls_today uint8 routines_today uint8 bit 0 morning, bit 1 bedtime snacks_today uint8 pillows_today uint8 last_play uint32 last_clean uint32 last_pet uint32 cs_minigames uint16 care-style counters for this stage cs_petting uint16 cs_cleaning uint16 cs_feeding uint16 cs_naps uint16 style_teen uint8 style_adult uint8 worn_head uint64 item ids; 0 = nothing worn_face uint64 worn_body uint64 worn_back uint64 items key id · index byowner (owner)
Wearables and other kept items.
6 FIELDS
id uint64 owner name template_id uint64 pet_id uint64 the pet wearing it; 0 = in the inventory serial uint32 limited editions only tradable bool
Once the contract is deployed, read a keeper's pets from any node, for example:
curl -s https://lb.libre.org/v1/chain/get_table_rows \
-H 'content-type: application/json' \
-d '{"code":"libregochi","scope":"libregochi","table":"pets",
"index_position":2,"key_type":"name",
"lower_bound":"alice","upper_bound":"alice","json":true}'Stats in a row are as stored at last_update. Decay since then is computed, not stored: the rules below give the current values, the same way the contract settles a pet before every action.
Game rules
- Stats run 0–100 and fall every hour: hunger 3, happy 2, energy 3, clean 2. A nap brings energy back at 25 an hour.
- Free care: 3 bowls a day, play every 1 h, a bath every 2 h, petting synced every 4 h.
- Hunger or hygiene at zero for 24 h makes a pet sick. Medicine cures it at once, or 12 h in a row of good care (hunger and hygiene at least 50) cures it for free. It never dies.
- Days are the keeper's local days, from a time zone they set once (
setoffset).
LEFT ALONE
SHOW THE NUMBERS
| Hour | Hunger | Happy | Energy | Clean |
|---|---|---|---|---|
| 0 | 100 | 100 | 100 | 100 |
| 6 | 82 | 88 | 82 | 88 |
| 12 | 64 | 76 | 64 | 76 |
| 18 | 46 | 64 | 46 | 64 |
| 24 | 28 | 52 | 28 | 52 |
| 30 | 10 | 40 | 10 | 40 |
| 36 | 0 | 28 | 0 | 28 |
| 42 | 0 | 16 | 0 | 16 |
| 48 | 0 | 4 | 0 | 4 |
| 54 | 0 | 0 | 0 | 0 |
| 60 | 0 | 0 | 0 | 0 |
| 66 | 0 | 0 | 0 | 0 |
| 72 | 0 | 0 | 0 | 0 |
CARED FOR
SHOW THE NUMBERS
| Hour | Hunger | Clean |
|---|---|---|
| 0 | 100 | 100 |
| 6 | 82 | 88 |
| 8 | 76 | 84 |
| 8 | 100 | 84 |
| 12 | 88 | 76 |
| 14 | 82 | 72 |
| 14 | 100 | 72 |
| 18 | 88 | 64 |
| 21 | 79 | 58 |
| 21 | 100 | 100 |
| 24 | 91 | 94 |
| 30 | 73 | 82 |
| 32 | 67 | 78 |
| 32 | 97 | 78 |
| 36 | 85 | 70 |
| 38 | 79 | 66 |
| 38 | 100 | 66 |
| 42 | 88 | 58 |
| 45 | 79 | 52 |
| 45 | 100 | 100 |
| 48 | 91 | 94 |
| 54 | 73 | 82 |
| 56 | 67 | 78 |
| 56 | 97 | 78 |
| 60 | 85 | 70 |
| 62 | 79 | 66 |
| 62 | 100 | 66 |
| 66 | 88 | 58 |
| 69 | 79 | 52 |
| 69 | 100 | 100 |
| 72 | 91 | 94 |
XP AND LEVELS
- XP comes from care, routines, petting, minigames and healthy days, and from one paid helper, the XP Snack (+25 XP, 1 per pet per day, not while sick). The free sources need the pet well (no stat under 20, not sick) and each has a daily cap per pet: care 40, routine 10, minigame 60, petting 10, healthy 10.
- Routines: +5 for looking after the pet between 6:00 and 10:00, and again between 20:00 and midnight, local time. +10 for the first action of each day while the pet is well.
- Minigames are skill only: up to 30 XP a play for 3 plays a day, and 60 a day at most. Scores are self-reported, which is why the caps exist: a made-up score gains no more than a good one.
- Streak: a day with 3 care actions (feed, play, clean, sleep) counts. Each streak day adds +10% to care XP, up to +50%. A free freeze comes every 7 streak days, at most 2 held.
SHOW THE NUMBERS
| Level | Total XP |
|---|---|
| 1 | 0 |
| 2 | 24 |
| 3 | 72 |
| 4 | 144 |
| 5 | 240 |
| 6 | 360 |
| 7 | 504 |
| 8 | 672 |
| 9 | 864 |
| 10 | 1,080 |
| 11 | 1,320 |
| 12 | 1,584 |
| 13 | 1,872 |
| 14 | 2,184 |
| 15 | 2,520 |
| 16 | 2,880 |
| 17 | 3,264 |
| 18 | 3,672 |
| 19 | 4,104 |
| 20 | 4,560 |
| 21 | 5,040 |
| 22 | 5,544 |
| 23 | 6,072 |
| 24 | 6,624 |
| 25 | 7,200 |
| 26 | 7,800 |
| 27 | 8,424 |
| 28 | 9,072 |
| 29 | 9,744 |
| 30 | 10,440 |
SHOW THE NUMBERS
| Day | Daily, free | Daily, misses 1 in 10 | Casual, once a day | Daily, buys helpers | Weekends only |
|---|---|---|---|---|---|
| 1 | 3 | 3 | 1 | 4 | 1 |
| 5 | 7 | 7 | 3 | 9 | 1 |
| 10 | 10 | 9 | 4 | 12 | 3 |
| 15 | 12 | 12 | 6 | 15 | 4 |
| 20 | 14 | 13 | 6 | 18 | 4 |
| 25 | 16 | 15 | 7 | 20 | 5 |
| 30 | 17 | 17 | 8 | 22 | 6 |
| 35 | 18 | 18 | 8 | 23 | 7 |
| 40 | 20 | 19 | 9 | 25 | 7 |
| 45 | 21 | 20 | 10 | 27 | 7 |
| 50 | 22 | 21 | 10 | 28 | 8 |
| 55 | 23 | 23 | 11 | 29 | 8 |
| 60 | 24 | 23 | 11 | 31 | 8 |
RAM and CPU
The contract pays the RAM for every row it creates. Players can't: new Libre accounts get 5,120 bytes and there's no RAM market. Purchases are handled in a transfer notification, where Leap's RAM_RESTRICTIONS doesn't let a contract bill the sender. And an extra action just to pay for RAM wouldn't read clearly on the wallet's signing sheet.
So nobody can drain it:
- rows have a bounded size;
- at most 30 pets and 300 items per keeper, and at most 10 pets and 10 items per gift;
- free starter eggs have a daily cap for everyone together.
SHOW THE NUMBERS
| Bytes | |
|---|---|
| Mainnet ask | 2,000,000 |
| Contract code and ABI | 1,136,438 |
| One keeper (2 pets, 3 items) | 1,723 |
| Keepers that fit | 501 |
| Ask for more at | 1,600,000 |
CPU and NET: the game is designed for at most 30 small transactions per keeper a day, each well under a millisecond, within what a Libre account with a weight of 1 gets (about 430 ms of CPU a day).
Nothing left to chance
- Pets are designed by the keeper, never rolled.
- Prices are fixed and shown before paying. Nothing paid for is decided by chance: no loot boxes, no draws, no gacha. Boxes, when they come, show their contents before purchase.
- Surprise comes from timing and published calendars. Nothing paid for or awarded depends on chance, so there is no draw to audit. Purely cosmetic moments, like the weather, may vary; they award nothing.
- Leaderboards give badges only. Contests are free to enter, judged by a named jury, with cosmetic prizes.
Security and keys
require_authon every action; only the two accepted tokens; exact prices; 128-bit split math with the remainder to the vault.- The contract uses no host functions Libre hasn't activated. The build fails if one sneaks in.
- Tests run the real contract in Vert against mainnet's token contracts, including an attacker contract that forwards fake transfers.
- No chain keys in code or CI. Mainnet deploys and admin actions are signing requests the owner signs in their own wallet. The contract starts paused and can be paused in an incident.
Coming at launch
- The contracts and rules go public, with a reproducible build and the WASM hash, so anyone can check that the code on chain is the code we publish.
- An external security review before mainnet.
- Questions or a bug? Email hello@libreslav.com. Libregochi is made by Libreslav, a Libre block producer.
Canonical address: https://libregochi.com/docs