Fishing
Lets the player cast a line over water, strike when a fish bites and reel it in without snapping the line, with the catch drawn from a fish table by zone, hour, weather and rarity.
Fishing (fishing.rod) #
What it is for #
Lets the player cast a line over water, strike when a fish bites and reel it in without snapping the line, with the catch drawn from a fish table by zone, hour, weather and rarity.
It needs input.actions, game.engine; installing it brings them in.
Turn it on #
Install the kit in a project, then change a setting (the values shown are its defaults):
gripforge_gamekit_install { project_id: "gkp_…", id: "fishing.rod" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "fishing.rod",
config: { "rodItem": "fishing_rod", "baitItem": "" } }
First example #
<!-- test: kits/game_engine/host/tests/fishing_rod.rs::a_cast_bites_is_struck_and_reeled_in --> This is the body of the passing test a_cast_bites_is_struck_and_reeled_in; the helper functions it calls are defined at the top of the same test file.
#[test]
fn a_cast_bites_is_struck_and_reeled_in() {
let mut s = session();
assert_eq!(
call(&mut s, "cast", json!([])),
json!({ "ok": false, "reason": "player" })
);
s.apply(&json!({ "op": "create", "kind": "player", "tags": ["player"], "components": { "transform": { "x": 0, "y": 0, "z": 0, "yaw": 0 } } }))
.unwrap();
assert_eq!(
call(&mut s, "cast", json!([])),
json!({ "ok": false, "reason": "water" })
);
call(&mut s, "placeSpot", json!(["pond", [0, 0, 6], 3]));
assert_eq!(call(&mut s, "zoneHere", json!([])), json!(["pond"]));
assert_eq!(
call(&mut s, "table", json!(["pond"])),
json!([{ "id": "carp", "name": "Carp", "rarity": "common", "chance": 1 }])
);
assert_eq!(call(&mut s, "cast", json!([])), json!({ "ok": true }));
step(&mut s, 31);
// The var keeps `waiting` through the bite (the web runtime publishes on the strike, not on the bite).
assert_eq!(s.host.state.get("fishing.state"), Some(&json!("waiting")));
assert_eq!(call(&mut s, "state", json!([]))["state"], json!("bite"));
assert_eq!(call(&mut s, "hook", json!([])), json!(true));
call(&mut s, "reel", json!([true]));
step(&mut s, 31);
assert_eq!(s.host.state.get("fishing.state"), Some(&json!("idle")));
assert_eq!(call(&mut s, "catches", json!([])), json!({ "carp": 1 }));
s.apply(&json!({ "op": "save" })).unwrap();
s.apply(&json!({ "op": "reload" })).unwrap();
assert_eq!(s.host.state.get("fishing.caught"), Some(&json!(1)));
}
Settings and defaults #
Descriptions come from the kit manifest and stay in English.
| Setting | Type | Default | Range or values | Meaning |
|---|---|---|---|---|
rodItem | string | "fishing_rod" | Item the player must hold to cast (empty: none needed). | |
baitItem | string | "" | Item taken at every cast (empty: no bait). | |
castDistance | number | 6 | 1–40 | How far ahead the float lands. |
biteMin | number | 3 | 0.2–120 | Shortest wait before a bite (s). |
biteMax | number | 9 | 0.2–300 | Longest wait before a bite (s). |
biteWindow | number | 1.2 | 0.1–10 | Seconds to strike once it bites. |
tensionRise | number | 0.6 | 0.01–5 | Tension added per second while reeling (plus the fish pull). |
tensionFall | number | 0.5 | 0.01–5 | Tension lost per second when not reeling (minus the fish pull). |
startTension | number | 0.4 | 0–0.95 | |
reelRate | number | 0.3 | 0.01–5 | Progress per second while reeling, divided by the fish difficulty. |
slipRate | number | 0.1 | 0–5 | Progress lost per second when not reeling. |
slackSeconds | number | 1.5 | 0.1–10 | A line slack (tension 0) this long lets the fish go. |
moveLimit | number | 3 | 0.5–20 | Walking this far from where you cast reels the line in. |
rarityWeights | object | {"common": 60, "uncommon": 25, "rare": 10, "l… | rarity → weight of a fish without its own weight (default common 60, uncommon 25, rare 10, legendary 3). |
Services, events, variables #
- Service
fishing.rod: cast() → { ok, reason? }, hook(), reel(on), cancel(), state(), table(zone, hour?, weather?), zoneHere(), catches(), spots(). - Events emitted:
fishing.cast(zone)fishing.bite(zone) — Strike within biteWindow.fishing.hooked(fish,rarity)fishing.caught(fish,item,rarity,size,stored)fishing.lost(reason,fish)
- Variables:
fishing.state(string) — Fishing statefishing.tension(number) — Line tensionfishing.progress(number) — Reel progressfishing.caught(number) — Fish caught
- Verbs of the scripting layer:
place_fishing_spot(action) — Mark water to fish in.fish_caught(condition) — That many of this fish (any fish when absent) were caught.
- Input actions:
fish
Hooks and modding #
- Hooks (a game or a mod can intercept them):
fish.cast(cancellable) — The line is about to be cast over zone (rod held, water under the float; asked before the bait is taken and before the wait is drawn).fish.bite(fields a tap may change:fish,window; cancellable) — The wait is over and fish was drawn: it is about to bite.fish.catch(fields a tap may change:item,size; cancellable) — The reel is complete and the size was drawn: fish is about to be landed and given as item (a trophy size, another reward).
- Moddable settings:
rodItem,baitItem,castDistance,biteMin,biteMax,biteWindow,tensionRise,tensionFall,startTension,reelRate,slipRate,slackSeconds,moveLimit,rarityWeights - Moddable collections:
fish - Components:
fishing_spot
Engines #
Declared targets: web, rust. gripforge kit api fishing.rod lists the exact settings and services of your version.
Versions #
Kit version 1.1.0.