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.

Source: module-kits:kits/fishing_rod/usage/en.mdView Markdown source

Also read offline — CLI: grip-forge docs fishing-rodMCP tool: gripforge_docs { "topic": "fishing-rod" }

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.

SettingTypeDefaultRange or valuesMeaning
rodItemstring"fishing_rod"Item the player must hold to cast (empty: none needed).
baitItemstring""Item taken at every cast (empty: no bait).
castDistancenumber61–40How far ahead the float lands.
biteMinnumber30.2–120Shortest wait before a bite (s).
biteMaxnumber90.2–300Longest wait before a bite (s).
biteWindownumber1.20.1–10Seconds to strike once it bites.
tensionRisenumber0.60.01–5Tension added per second while reeling (plus the fish pull).
tensionFallnumber0.50.01–5Tension lost per second when not reeling (minus the fish pull).
startTensionnumber0.40–0.95
reelRatenumber0.30.01–5Progress per second while reeling, divided by the fish difficulty.
slipRatenumber0.10–5Progress lost per second when not reeling.
slackSecondsnumber1.50.1–10A line slack (tension 0) this long lets the fish go.
moveLimitnumber30.5–20Walking this far from where you cast reels the line in.
rarityWeightsobject{"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 state
    • fishing.tension (number) — Line tension
    • fishing.progress (number) — Reel progress
    • fishing.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.