> ## Documentation Index
> Fetch the complete documentation index at: https://flux-docs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Send events in both directions and make your first client-to-server invocation.

Flux has two entry points. Call `Flux.Server(name)` on the server and
`Flux.Client(name)` on the client with the same name, and the two objects are
connected.

<Note>
  The name is the channel identifier. It is written into every packet as a
  length-prefixed string, so both sides have to agree on it exactly. Matching is
  case-sensitive.
</Note>

## Server example

```luau ServerScriptService/Example.server.luau icon="server" theme={null}
l-- server
local Flux = require(game.ReplicatedStorage.Flux)
local Ping = Flux.Server("Ping")

Ping:Connect(function(player, msg)
    print("got", msg, "from", player)
end)
```

## Client example

```luau StarterPlayerScripts/Example.client.luau icon="desktop" theme={null}
-- client
local Flux = require(game.ReplicatedStorage.Flux)

Flux.Client("Ping"):Fire("hello")
```

## Reliable and unreliable delivery

Every Flux event carries both channels. There is no second object to create, so pick
the method that matches the message.

<CodeGroup>
  ```luau Reliable theme={null}
  -- Guaranteed delivery, ordered. Use for state changes.
  Damage:Fire(player, 25)
  Damage:FireAll(roundWinner)
  ```

  ```luau Unreliable theme={null}
  -- May be dropped or reordered. Use for high-frequency, disposable data.
  Position:FireUnreliable(player, character.PrimaryPart.CFrame)
  Position:FireAllUnreliable(tick())
  ```
</CodeGroup>

<Tip>
  Unreliable packets are subject to Roblox's `UnreliableRemoteEvent` size limit. Keep
  them to a single small payload, such as a `CFrame` or a couple of numbers, and never
  rely on them arriving.
</Tip>

## Client-to-server invocations

An invocation is a round trip. The client sends a request, the server's `OnInvoke`
handler runs, and its return values come back to the caller.

<CodeGroup>
  ```luau Server theme={null}
  local Shop = Flux.Server("Shop")

  Shop.OnInvoke = function(player, itemId: string)
  	local ok = grantItem(player, itemId)
  	if not ok then
  		error("Insufficient funds")
  	end
  	return true, itemId
  end
  ```

  ```luau Client theme={null}
  local Shop = Flux.Client("Shop")

  -- Invoke yields the calling thread until the server responds.
  local ok, purchased = Shop:Invoke("sword")
  print(ok, purchased) --> true sword
  ```
</CodeGroup>

`Client:Invoke` errors if the server handler errors or if the request times out, so
wrap it when failure is expected:

```luau theme={null}
local success, result = pcall(function()
	return Shop:Invoke("legendary_sword")
end)

if not success then
	warn("Purchase failed:", result) --> "Insufficient funds"
end
```

<Warning>
  Invocations only run from client to server. The server has no `Invoke` method and
  the client has no `OnInvoke` property. See
  [Invocations](/guides/invocations#direction) for the pattern to use when you need
  data from a client.
</Warning>

## Adding a schema

Passing a schema replaces the dynamic encoder with a fixed layout. It removes the
per-value type tag from every argument and narrows numbers to the width you declare.

```luau highlight={4-7} theme={null}
local Flux = require(ReplicatedStorage.Flux)
local T = Flux.Types

local Damage = Flux.Server("Damage", {
	T.Instance(),  -- the humanoid that was hit
	T.UInt16(),    -- damage amount, 0-65535
})

Damage:FireAll(humanoid, 250)
```

Declare the same schema on both sides, then read on for the full rules.

<CardGroup cols={2}>
  <Card title="Schemas" icon="ruler" href="/guides/schemas">
    Fixed layouts, composites, and when they pay off.
  </Card>

  <Card title="Generics" icon="shapes" href="/guides/generics">
    Get real autocomplete on `Fire`, `Connect` and `Invoke`.
  </Card>
</CardGroup>
