Skip to content

Gameplay API

ESTONlA edited this page Sep 8, 2026 · 1 revision

Gameplay API

Added in 0.3.0. These APIs expose selected native game operations, not arbitrary C# objects. Use dot syntax. All gameplay mutations require the local game to be hosting. Clients cannot invoke them remotely. Queries normally return nil or an empty array outside a hosted session; validated arguments are still required.

Shared Rules

  • Steam IDs are decimal strings from player snapshots. Network item IDs are decimal strings from current item snapshots. They are different identifiers. Item definition, NPC, bait, slot and upgrade indices are integers.
  • Lua tables and arrays are snapshots. Editing them does not alter the game. Arrays are one-indexed, but explicit game index fields such as slot, index and id preserve the game's zero-based indices.
  • Invalid argument types, non-finite numbers, fractional indices and out-of-range values raise a Lua error and disable the script. Missing objects or unready state normally return false/nil instead.
  • Mutation results report readiness/acceptance, not guaranteed remote acknowledgement. Vanilla invulnerability, initialization or another mod may affect the outcome.
  • Spawn/despawn, travel, upgrades, grants and saves can change the world permanently when saved. Test on a spare world. Upgrade/grant functions do not charge money unless explicitly described as spending.
  • Game events are queued notifications, never cancellation filters. Scripts can produce feedback loops even with queue limits. Only install trusted scripts; there is no hard memory quota or per-query CPU quota.

Catalog

Function Result
htf.catalog.items() Available spawnable prefab definitions, including whether each is allowed by this framework.
htf.catalog.item(id) One definition or nil; ID 0-255.
htf.catalog.baits() Bait definitions with IDs, localized names/descriptions, cost, reeling requirement, loss chance, min/max catch time and weighted fishable asset names.
htf.catalog.attachments() Attachment IDs, availability flags, localized names and descriptions. Read-only, not an attachment installation API.

Catalog queries wait for an initialized, non-loading host world. Definitions include id, name, prefab_name, type, default_worth, cost, is_fish, is_weapon, buoyancy, model_height, ignored_by_birds, ignored_by_shop, spawn_allowed, skin_count, and optional creature data. Bait weights are relative weights, not normalized probabilities; names are asset identifiers, not item handles.

Creature definition fields are max_health, endangered, boss_type, boss_health_multiplier, boss_duration, fullness_restored, health_restored, ignores_water_death and excluded_from_journal. Some creature reward stats reflect the game's current cookness-based calculation.

Items

Function Result / bounds
htf.items.list(offset, limit) Basic snapshots ordered by network ID. Defaults: offset 0, limit 64. Offset 0-1000000, limit 1-256.
htf.items.get(network_id) Detailed snapshot or nil.
htf.items.nearby(x, y, z, radius) Up to 256 snapshots, closest first, radius 0-1000.
htf.items.spawn(definition_id, x, y, z, yaw) New basic snapshot or nil. Yaw optional, default 0. Uses the native networked spawn factory.
htf.items.despawn(network_id) Request normal native destruction of an eligible loose item; boolean.
htf.items.cook(network_id, amount) Add 0-2 cookness to an ordinary creature; native result clamps to 0-2.
htf.items.set_skin(network_id, index) Set a valid skin index on this item. Does not unlock the skin in a player's collection.
htf.items.set_interactable(network_id, enabled) Toggle interaction on an eligible loose item. Native code also freezes/unfreezes physics.
htf.items.set_score_multiplier(network_id, multiplier) Set the item's kill-score multiplier, 1-100, only while its current multiplier is 1. Native code does not allow replacing an already assigned bonus.
htf.items.damage(network_id, damage) Apply 0-100000 integer damage to a living creature through its server health method. Boss immortality remains respected.

Coordinates must be finite and between -100000 and 100000; yaw is -360 to 360. No terrain/collision safety check is performed. Spawns require a ready host world, native item manager and dynamic-object holder. The shared Lua spawn budget allows 8 attempts per second and 128 live tracked Lua-spawned items. Reloading scripts does not clear this live-item cap. Removed objects free capacity. Nil can mean unready state, missing/protected prefab or a reached limit.

Bosses, player corpses and quest-marked prefabs are protected from spawn. Despawn/interaction changes also reject these protected objects and anything held by a player, stored in inventory, attached to a rod or held by a bird. despawn uses native destruction and may complete after a delay. It is not an unrestricted cleanup command.

Network IDs are session-local and may be reused. Do not persist them or assume a later lookup identifies the same object. List pagination is a live view, not an atomic inventory; objects can disappear between calls.

Detailed item snapshots extend the basic item snapshot with definition, holder_id, last_holder_id, in_inventory, can_pick_up, interactable, skin, cookness, weight, killscore_multiplier, betting_multiplier, has_been_held, attached_rod_id and Euler rotation. Creatures add authoritative health, dead, and drip. Optional physics contains the game's observed velocity, angular_velocity, floating, on_boat, stationary and simulator_id; remote physics observations can lag.

Inventory

Function Result / bounds
htf.inventory.get(steam_id) Capacity, extra pockets, selected slot, selected bait, slot records and owned bait counts.
htf.inventory.contains(steam_id, network_id) Whether the player's native inventory contains the item.
htf.inventory.select_slot(steam_id, slot) Select a populated unlocked slot on a living player, or -1 to deselect.
htf.inventory.set_bait(steam_id, bait_id) Select an owned bait; 0 selects the default bait.
htf.inventory.give_bait(steam_id, bait_id, count) Grant 1-100 units of an existing non-default bait. No money is deducted.
htf.inventory.pocket_cost(steam_id, extra_pocket_index) Native cost or nil; extra-pocket indices start at 1.
htf.inventory.unlock_pockets(steam_id, total_extra) Increase extra pockets within the player's native slot/cost-array limits. Never removes pockets or charges money.

Each slots entry has slot, unlocked and optional item. Locked/empty slots are retained. owned_baits entries use explicit {id, count} fields; their array position is not a replacement for bait ID. The native game's inventory serialization, selection and callbacks remain responsible for networking these changes.

Players and Combat

Function Result / bounds
htf.players.local_player() Host's local player snapshot, or nil.
htf.players.held_item(steam_id) Currently held item snapshot or nil.
htf.players.damage(steam_id, damage) Apply 0-1000 integer base damage to a living player. Native difficulty scaling, AFK protection, invulnerability and god mode still apply.
htf.players.poison(steam_id) Apply native poison to a living player.
htf.players.ignite(steam_id) Apply native fire to a living player.
htf.combat.weapon(network_id) Damage, ADS settings, sight/barrel/ammo-type indices, extended-magazine/laser flags and current/next bullet upgrades.
htf.combat.melee(network_id) Sharpness index and current/next sharpness upgrade.
htf.combat.upgrade_bullets(network_id) Grant one next bullet upgrade if available. Does not charge money.
htf.combat.sharpen(network_id) Grant one next sharpness upgrade if available. Does not charge money.

Player snapshots now also include authoritative raw poison and fire counters. Existing heal/feed/teleport APIs remain available. Combat upgrade records contain damage and cost; next_upgrade is nil at the cap. Ammunition count is deliberately not reported as authoritative for remote players.

Server and Economy

Function Result / bounds
htf.server.settings() friendly_fire, one_shot, difficulty enum name, health/damage multipliers; nil without initialized host settings.
htf.server.set_friendly_fire(enabled) Set native friendly fire, boolean input.
htf.server.set_one_shot(enabled) Set native one-shot state idempotently, boolean input.
htf.server.set_difficulty(name) easy, default or hard, case-insensitive.
htf.server.save() Request a native world save if ready. Shared cooldown: one request per 5 seconds. True does not guarantee disk persistence.
htf.economy.can_afford(amount) Compare authoritative shared funds against an integer amount, 0-1000000, on the host.
htf.economy.give(amount, actor_id) Add shared money. Optional actor is a Steam ID for native effects; defaults to host's local player. Rejects overflow.
htf.economy.spend(amount, actor_id) Remove shared money only if sufficient funds exist. Same actor/amount rules as give.

These are shared funds, not personal bank accounts. htf.money(amount) remains compatible. Save failures may be handled internally by the game: watch its log. Save-request events can themselves trigger scripts, so do not save unconditionally on every save notification. Native server rules are not Steam lobby visibility controls.

Boat

Function Result / bounds
htf.boat.info() Position/rotation, observed velocity/angular velocity/speed, unlock/radar state, motor/skin indices and counts, driver snapshot and driver position.
htf.boat.unlock() Grant boat unlock.
htf.boat.unlock_radar() Grant radar unlock.
htf.boat.upgrade_motor(index) Set an existing motor tier at least as high as the current one; no downgrade or charge.
htf.boat.set_skin(index) Apply an existing skin without unlocking it in a collection.
htf.boat.eject_driver() Clear the current driver, or false if none.
htf.boat.return_to_spawn() Eject the driver and move the boat using its native manager, requiring a non-loading host world.

All boat actions require an initialized network boat. Returning the boat can leave passengers behind; this is not a teleport-everyone operation. Native upgrade/skin array bounds are checked before calling the game.

World

Function Result / bounds
htf.world.islands() Playable island indices with unlocked and current flags. Follows the native travel range, excluding the final non-travel scene.
htf.world.travel(index) Request a crew/boat island transition through the native travel method. Existing boat required; refuses same-island/loading requests. Shared cooldown: one request per 2 seconds.
htf.world.unlock_island(index) Raise native island unlock progression, within playable bounds.
htf.world.water_at(x, y, z) Water height, signed depth and underwater flag at a world position.
htf.world.rules() Read-only headshot multiplier, velocity limits, kill/death forces, boat projectile force, fish velocity-damage settings and seed.

Travel is a host tool and can visit locked playable islands; it does not automatically unlock them. It can unload loose items and relocate the crew. Island indices are not invented map IDs: use world.islands(). All these queries/actions wait for a ready host world.

Bosses

Function Result / bounds
htf.bosses.info() Current boss item, authoritative health, observed maximum health/immortality and spawn/leave/duration ticks.
htf.bosses.set_immortal(enabled) Toggle native immortality for the current living boss.
htf.bosses.scaled_health(base_health, multiplier) Native player-count-scaled HP; base 1-100000, multiplier 0-10 (default 0.5).
htf.bosses.scaled_damage(base_damage, multiplier) Native player-count-scaled damage; base 0-100000, multiplier 0-10 (default 0.2).

Ticks are game network ticks, not wall-clock seconds. Scaling queries do not spawn or modify a boss. world.boss() remains the simpler basic snapshot query. Boss spawning is not enabled by the item factory API.

NPCs and Quests

Function Result / bounds
htf.npcs.list() Registered scene NPC snapshots ordered by ID.
htf.npcs.get(npc_id) Snapshot or nil; integer ID 0-255.
htf.npcs.quests(npc_id) Quest definitions/current native progression for that NPC.
htf.npcs.progression() Grill-unlocked and final-boss-killed flags.
htf.npcs.unlock_grill() Grant native grill unlock. Does not mark arbitrary quests completed.

NPC snapshots contain id, scene object name, position, mouth_position, quest_count and holding_item. Names are scene identifiers, not guaranteed localized display names. Quest records include index, available, asset name, type, total_items, progress, only_creatures, island_to_unlock, optional bait_reward and required item_ids. Native quest progression can reset after completion; it is not a permanent completion-history flag.

Verification

These bindings compile against the installed game and have static contract checks plus Lua/helper/example tests. Actual spawning, remote inventory changes, upgrades, travel and saving still need in-game multiplayer verification. See Examples for the optional World Tools script and Architecture for extending these modules.

Clone this wiki locally