# Using arclib

This is a guide for downstream developers intending to use arclib to create game-specific integration mods.

## Quick Start

### Installation

Add `arclib` to your mod's dependencies in `mod.conf`:

```toml
depends = arclib
```

### Basic Usage

```lua
-- Create a manager instance
local manager = arclib.manager({
	url_target = "wss://archipelago.gg:38281",
	login_slotname = "PlayerName",
	login_gamename = "Your Game Name",
	modstore = core.get_mod_storage()  -- For persistence
})

-- Set up event handlers
manager.on("update", function()
	-- Handle state updates (items received, locations checked, etc.)
	local state = manager.state
	if state.items_received then
		-- Process received items
	end
end)

manager.on("printtext", function(text)
	-- Display chat messages from Archipelago
	core.chat_send_all(text)
end)
core.register_on_chat_message(function(_, msg)
		-- Relay local chat to archipelago
		manager:say(msg)
	end)

-- Load saved connection configuration
arclib.ux.configure({
	modstore = modstore,
	manager = manager
})

-- Chat command to access config UI
core.register_chatcommand("ap", {
	description = "Show Archipelago config form",
	func = function(name)
		arclib.ux.configure({
			modstore = modstore,
			player = name,
			manager = manager,
		})
	end
})
```

## API Reference

### Manager (`arclib.manager`)

The main interface for Archipelago connections.

Handles automatic reconnects and message resends, including persisting queued reliable messages across restarts.  Maintains a cached replicated state from the server, including across disconnects.

#### Constructor
```lua
local manager = arclib.manager(options)
```

##### Options

- `modstore`: Luanti mod storage for persistence
- `storeprefix`: Optional prefix for storage keys
- `url_target`: Archipelago WebSocket URL
- `url_proxy`: HTTP proxy URL (default: `http://localhost:9839`)
- `login_slotname`: Player slot name
- `login_gamename`: Game name
- `login_password`: Optional room password

#### Methods

- `manager:open()` - Start connection
- `manager:close()` - Stop connection
- `manager:check_location(locations)` - Check location(s) by name or ID (reliable)
- `manager:goal_complete()` - Send goal completion (reliable)
- `manager:say(text)` - Send chat message
- `manager:flush_send_queue()` - Manually flush pending messages

#### Events

- `update` - State updated from server (any data update received, including partial state during startup)
- `printtext` - Chat message received (from PrintJSON) and parsed
- `disconnect` - Connection lost
- `rejected` - Connection rejected by server
- `cmd:*` - Specific Archipelago commands, following Archipelago protocol's TitleCase naming

### Connection (`arclib.connection`)

Low-level protocol handler (used internally by manager).  Not intended for downstream use, exported as-is.

### WebSocket (`arclib.websocket`)

HTTP-to-WebSocket bridge client.  Not intended for downstream use, exported as-is.

### Utilities (`arclib.util`)

- `create_emitter()` - Create event emitter functions
- `deepcopy(src)` - Deep copy tables with cycle support
- `generate_uuid()` - Generate UUID v4
- `log(level, ...)` - Structured logging
- `print_json_convert(state, data)` - Convert PrintJSON to text
- `structstore(modstore, prefix)` - Persistent structured storage

### UX (`arclib.ux`)

- `configure(options)` - Load stored configuration / show configuration UI

### Item Visualization (`arclib.itemvis`)

Standard pseudo-3D visualization for Archipelago items, creating ephemeral visual models that aren't stored in the map.

#### Constructor
```lua
local vis = arclib.itemvis.add(options)
```

##### Options
- `pos` (required): Center position for the visual
- `check` (optional): Function returning truthy to keep visual, auto-destroy if falsy
- `applied_to_node` (optional): Node name this visual is attached to

#### Methods
- `vis:remove()` - Destroy the visual model
- `vis:explode()` - Destroy with particle explosion effect
- `vis:move_to(pos)` - Move the visual to a new position

#### Node Integration
- `arclib.itemvis.node_apply(pos, node)` - Apply visualization to a specific node
- `arclib.itemvis.node_register(nodenames)` - Register visualization for node types via ABM/LBM
- `arclib.itemvis.check_all()` - Manually trigger validation check

#### Utility Functions
- `arclib.itemvis.inside_radius(pos, radius)` - Find all itemvis instances within radius, returns array

#### Usage Example
```lua
-- Create a floating item visualization at a position
local vis = arclib.itemvis.add({
    pos = {x = 100, y = 10, z = 200},
    check = function()
        -- Keep visual only while condition is true
        return some_condition
    end
})

-- Create a node using itemvis for display.
core.register_node(modname .. ":apitem", {
		drawtype = "airlike",
		paramtype = "light",
		sunlight_propagates = true,
		walkable = false,
		on_construct = arclib.itemvis.node_apply,
		after_destruct = arclib.itemvis.node_apply,
		on_punch = function(pos)
			-- (Replace with your method of accessing manager and getting Location ID)
			api.manager:check_location(core.get_meta(pos):get_float("location_id"))
			for _, v in ipairs(arclib.itemvis.inside_radius(pos, 0.5)) do
				v:explode()
			end
			core.remove_node(pos)
		end
	})
arclib.itemvis.node_register({modname .. ":apitem"})
```

## Architecture

```
Your Mod
	↕
arclib.manager
arclib.connection
arclib.websocket
	↕ (HTTP)
External websockproxy
	↕ (WebSocket)
Archipelago Server
```