Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Season 3.1 #263

Merged
merged 25 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
236 changes: 236 additions & 0 deletions GAMEJAM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
# CAIRO

Project actually uses dojo v0.3.15.
to install matching toolchain version (katana, sozo, torii) just `dojoup -v v0.3.15`.

## Models

Game Models, types (stucts/enums) & simples helpers impl (into, introspection on enums,..)

#### Game
Stores Game related informations like game_mode (actually used for testing to load different settings), start_time & max_turns.

Some legacy fields (max_players, num_players, creator) are not used atm.
(Actually thoses fields could sit in Player as there is always 1 Game for 1 Player)

#### Player
Represent a Player in a Game. (keys are `game_id` & `player_id`)
Common player infos (name, avatar, ..)
Game related infos (cash, health, location, ..)

status: PlayerStatus is used for handling special events in game loop (Normal is default, AtPawnshop for when player can access it, BeingMugged/BeingArrested when doing encounters while traveling )

#### Location (not a model)
This is not a model, just enum/helpers to handle Locations

#### Drug
Stores quantity of each drug owned by a Player for a Game
(keys : `game_id`, `player_id`, `drug_id`)

#### Item
Stores Items owner by a Player for a Game
(keys : `game_id`, `player_id`, `item_id`)

#### Market
Stores "liquidity pools" for a Game, 1 pool for each drug (x6) and each location (x6) --> 36 pools
(keys: `game_id`, `location_id`, `drug_id`)

Each pool contains cash & quantity for a drug at a location in the current game and act as a uniswapV2 pool.

#### Encounter
Stores encounters for a Player in a Game
(keys: `game_id`, `player_id`, `encouter_id`)

There is 2 types of encounters (Gangs/Cops)
level, health, payout( what you earn if you beat em), demand_pct(how much they want in %)

#### Ryo
Store RYO related infos.
Actually only used for handling leaderboards (with leaderboard_version).

It should be initialized after migration

#### Leaderboard
A new leaderboard version is created if there has been no new highscore for a configurable period (1 day / 1 week ..)
It stores the `high_score` & `next_version_timestamp` for a leaderboard version.


## Systems

Contracts with callable entrypoints

#### Ryo
This is use to initialize RYO related infos

Actually used to setup first leaderboard.

#### Lobby
Entrypoint to create a game via `create_game`.

Initialize Game & Player models with settings.

Initialize Markets (lps for each location/drug)

Emit events

#### Travel
At game start you have to chose a location, this is done calling `travel` function.

It checks your player_status (you cannot travel if you are AtPawnshop or Being Mugged/Arrested) and other stuff (max_turns, valid location_id, ..)

If you don't make encounter, you land in the desired location and can sell drugs for profit$.

If you meet Cops or Gangs, player_status is changed and you'll have to make decisions.

Also handles end game if you are at max_turns, you end game calling `end_game`.

An help fn `on_turn_end` is used to handle turn_end.
A turn can end from travel, decide, or shop (when leaving pawnshop).

It check if player should be redirected to pawnshop, update turn number & wanted. And call `market::market_variations` to make prices changes.

#### Decide

`decide` function is used to handle player choices (fight, pay, run).
When meeting encounter, you only can `decide` until resolution. Events are emitted for each decision to be handled by front.

When resolved it then change you player_status to Normal
& call the `travel::on_turn_end` fn.

#### Shop

When player_status is AtPawnshop, you can either `buy_item` or `skip`. Notice they both call the `travel::on_turn_end` fn too to handle turn end.

`available_items` is called by front to compute which items are buyable.

#### Trade

Allow player to `buy` or `sell` drugs at his location.

It uses uniswapV2 constant product formula x * y = k

### Constants

`const SCALING_FACTOR: u128 = 10_000;`
Its used for cash precision (100 is stored as 100 * SCALING_FACTOR = 1_000_000 )

## Utils

#### Settings

This is where almost all settings are set.
There is differents traits for diff kinds of settings (SettingsTrait, DrugSettingsTrait, PlayerSettingsTrait..) used to retrieve settings for given parameters.

All settings traits use game_mode.Its been used to handle 2 games modes (limited turn nb / unlimited) and is actually used to for testing and allow to override default settings.

(ex: to test encounters & death, set a default high wanted(% chance of making encounters) and a low hp level)

#### Events

Helper to emit raw events (could probly be removed now)

#### Random

Helper to handle 'randomness'

#### Math

Helpers for some math operations `add_capped` & `sub_capped`

#### Market

Helpers to manage Markets (initialization, price variations, inflation xd)

#### Risk

Helpers to handle risks while traveling / runing

#### Shop

Helper to check if shop is opened for a given player

#### Leaderboard

Helpers to handle Leaderboards

`on_game_start` is called at each game start to check if current leaderboard should be historized

`on_game_end` check if its a new highscore & update it, and reset next_version_timestamp.


## WEB / NEXT.JS

### Most useful files

`/dojo/hooks/useSystems.ts` : smart contracts interactions calls

`/dojo/queries/*` : hooks to deal with graphQL

`/dojo/events.ts` : event types & parsing

`/graphql/*` : graphql queries & subscriptions used by codegen to gen `/generated` using `yarn gen` or `scarb run gendojo`

`/hooks/player.tsx` : handle graphql subscriptions for a player/game

### Most useless files

`/dojo/generated` : this is some mainly unused generated code, **only contractEvents > WorldEvents is used**

`/dojo/setup/create*` : unused


## HOW TO

### Add a new field to Player model

#### CAIRO

- update `models/player.cairo` to add a new field
- (*optionnal*) add a PlayerSettings in `utils/settings.cairo` if needed
- update `systems/lobby.cairo` to initialize field at game start
- do what you want with this field in cairo code

Launch katana
`katana --disable-fee`

Launch torii, we will need it for graphql codegen
`torii --world_address [deployed_world_address]`

use sozo to build & migrate
`sozo build && scarb run migrate`

check [readme](./README.md) for more details

#### FRONT END

- add field to `PlayerProps` in `graphql/entities.graphql`

it will be retrieved by the `PlayerEntity` query which retrieve player state & all related datas ( drugs, items, encounters)

it will be updated thx to `PlayerEntitySubscription` graphql subscription

- since we have a new field to query, we have to launch graphql codegen with `yarn gen` ( this will call torii )

`/generated/graphql.ts` & `/generated/introspections.ts` will be updated
you should see your new field in `type Player` & `PlayerPropsFragmentDoc`

- in `dojo/queries/usePlayerEntity` add your field in `class PlayerEntity`, handle it in `constructor` & `update`

- use field in UI, for ex `components/Header.tsx`
we retrieve playerEntity using playerEntityStore from useDojocontext() :

#### ENJOY

```rust
const { playerEntityStore} = useDojoContext();
const { playerEntity } = playerEntityStore;`

if (player.entity.swag_level === 420 ) {
console.log("blaze it")
}
```





25 changes: 18 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,38 +27,49 @@ sozo migrate
# Start indexer, graphql endpoint at http://localhost:8080
torii --world {world_address}

# Setup default authorization
# Setup default authorization & initialization
./scripts/default_auth.sh [local]

# Copy manifest.json into web directory & do graphql/ts codegen
./scripts/gen.sh

# Start frontend, located at http://localhost:3000
cd web
yarn install && yarn dev
```

Note: If the world address your game is deployed to is different, you'll need to update it in three places currently
In Scarb.toml, there is various shortcut defined using scripts.
For exemple `scarb run migrate` will execute `sozo migrate` then gen.sh / default_auth.sh

- Scarb.toml
- script/default_auth.sh
- web/src/constants.ts
```bash
sozo build && scarb run migrate
```

#### Any errors when doing `sozo build` ?

This might be because your version of sozo is not correct.

Check the `Scarb.toml` file and get the `rev` tag from the `dojo` dependency:
Check the `Scarb.toml` file and get the `rev` or `tag` from the `dojo` dependency:
```toml
[dependencies]
dojo = { git = "https://github.com/dojoengine/dojo.git", rev = "ca2d2e6dd1ef0fe311310ba0728be8743b1d5cc8" }
# or
dojo = { git = "https://github.com/dojoengine/dojo.git", tag = "v0.3.15"}
```

In this example, this is how we would install the correct version:
In this example, this is how we would install the correct `rev` version:
```bash
git clone https://github.com/dojoengine/dojo.git
cd dojo
git checkout ca2d2e6dd1ef0fe311310ba0728be8743b1d5cc8
dojoup -p .
```

For tagged version, you can use dojoup:
```bash
dojoup -v v0.3.15
```

This will reinstall the binaries in your `~/.dojo/bin` folder.

### With Madara
Expand Down
7 changes: 4 additions & 3 deletions Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ version = 1

[[package]]
name = "dojo"
version = "0.3.10"
source = "git+https://github.com/dojoengine/dojo.git?tag=v0.3.10#be1676252c41f8188465741edcbcb381d2c12080"
version = "0.3.15"
source = "git+https://github.com/dojoengine/dojo.git?tag=v0.3.15#cdbaca4121b1642e1a8ca40d6831bad73d28ed26"
dependencies = [
"dojo_plugin",
]

[[package]]
name = "dojo_plugin"
version = "0.3.10"
version = "0.3.11"
source = "git+https://github.com/dojoengine/dojo?tag=v0.3.11#1e651b5d4d3b79b14a7d8aa29a92062fcb9e6659"

[[package]]
name = "rollyourown"
Expand Down
34 changes: 20 additions & 14 deletions Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,44 @@ sierra-replace-ids = true

[dependencies]
# cubit = {git = "https://github.com/influenceth/cubit.git"}
# dojo = {git = "https://github.com/dojoengine/dojo.git"}
dojo = {git = "https://github.com/dojoengine/dojo.git", tag = "v0.3.15"}
# dojo = {git = "https://github.com/dojoengine/dojo.git", rev = "d7f46502cba3d6462b68a4dfb07336377bca2678"}
dojo = {git = "https://github.com/dojoengine/dojo.git", tag = "v0.3.10"}


[[target.dojo]]

[scripts]
katana = "katana --disable-fee --invoke-max-steps 999999999"
build = "sozo build && scarb run gendojo"
gendojo = "./scripts/gen.sh"
auth = "./scripts/default_auth.sh local"
auth_dev = "./scripts/default_auth.sh"
migrate = "sozo migrate && scarb run gendojo && scarb run auth"
migrate_dev = "sozo migrate --rpc-url https://api.cartridge.gg/x/ryo/katana --account-address 0x6e857786bbd1652857d673836c41e0544d9d5ecd3e7a1bbde744e328b8cc2f6 --private-key 0x5e9d85de083b7ddd3029c44de2997ceba8384074bbebb66696a1b507f0466fc"

[tool.dojo.env]
# Katana
auth = "./scripts/default_auth.sh dev"
auth_staging = "./scripts/default_auth.sh staging"
auth_prod = "./scripts/default_auth.sh prod"
migrate = "sozo -P dev migrate && scarb run gendojo && scarb run auth"
migrate_staging = "sozo -P staging migrate"
# migrate_staging = "sozo migrate --rpc-url https://api.cartridge.gg/x/ryodev/katana --account-address 0x6e857786bbd1652857d673836c41e0544d9d5ecd3e7a1bbde744e328b8cc2f6 --private-key 0x5e9d85de083b7ddd3029c44de2997ceba8384074bbebb66696a1b507f0466fc"
migrate_prod = "sozo -P prod migrate"

[profile.dev.tool.dojo.env]
rpc_url = "http://localhost:5050"
account_address = "0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973"
private_key = "0x1800000000300000180000000000030000000000003006001800006600"
rpc_url = "http://localhost:5050"

# seed 420
# [profile.staging.tool.dojo.env]
# rpc_url = "https://api.cartridge.gg/x/ryodev/katana"
# account_address = "0x6e857786bbd1652857d673836c41e0544d9d5ecd3e7a1bbde744e328b8cc2f6"
# private_key = "0x5e9d85de083b7ddd3029c44de2997ceba8384074bbebb66696a1b507f0466fc"
# rpc_url = "https://api.cartridge.gg/x/ryo/katana"

# [profile.prod.tool.dojo.env]
# rpc_url = "https://api.cartridge.gg/x/ryoprod/katana"
# account_address = "0x6e857786bbd1652857d673836c41e0544d9d5ecd3e7a1bbde744e328b8cc2f6"
# private_key = "0x5e9d85de083b7ddd3029c44de2997ceba8384074bbebb66696a1b507f0466fc"

[tool.dojo.world]
name = "Roll Your Own"
description = "example world"
description = "Onchain adaptation of the classic Drug Wars game. An immersive recreation of the 1999 TI-83 classic where street smarts reign supreme and every choice matters in the end."
website = "https://rollyourown.preview.cartridge.gg/"
icon_uri = "file://assets/icon.png"
cover_uri = "file://assets/cover.png"
socials.x = "https://x.com/TheDopeWars"
socials.x = "https://x.com/TheDopeWars"

Loading
Loading