# How Atlas Kit reads the game
Documentation: next (source: develop).

Install the preview: `pnpm add @aephia/atlas-kit@next`. These docs follow develop and may include changes not yet published to npm.

> Five rules that explain the shape of every read in this SDK.

Markdown source of https://develop.atlas-kit-docs.pages.dev/start-here/how-it-thinks/ — see https://develop.atlas-kit-docs.pages.dev/ai/ for the full machine-readable surface.

Five rules explain almost every API in this SDK. Knowing them means you can
usually guess how something works instead of looking it up.

## 1. Everything hangs off a context

A context holds the cache, the RPC binding, and the cluster's known addresses.
Creating one is synchronous and does no network work.

```ts
const sage = createSageClient({ cluster: 'zink-ptr', rpc });
```

There is no global `init()`. Two contexts are genuinely independent — separate
caches, separate endpoints — which is what makes it safe to run several in one
process.

If you prefer functions to objects, `createSageContext` gives you the context
alone, and every domain function takes it as its first argument. The convenience
client is a thin wrapper over exactly those functions.

## 2. Reads return loaded data

There are no two-phase handles. When a read resolves, the data is there.

```ts
const character = await sage.characters.forProfile(profileAddress);
character.address; // already loaded
```

Anything that costs a network round trip is a **method you call**, not a
property you read. `character.fleets.all()` is a
separate read, so it is a separate `await`. If it looks like a property, it is
already in memory.

## 3. Nothing is trusted until it is validated

Every account read is checked before decoding: program owner, discriminator,
data shape, minimum length. Data that fails produces a typed error and never
enters the cache.

This matters more than it sounds. An RPC can return anything — a wrong account,
a truncated response, an account from a different program. Without validation
those become silently wrong values deep in your application. Here they become
an error at the read.

## 4. The cache is keyed by identity, not by call

Two reads of the same account through the same context return the same
immutable snapshot until it expires. Not an equal copy — the same object.

The key is cluster, program, account type, and address. Reading a fleet through
`character.fleets.all()` and reading it directly hit the same cache entry.

Every snapshot carries provenance: where it came from and when. So "is this
fresh?" is always answerable, and the [interactive
examples](/start-here/first-read/) will later let you watch caching happen.

## 5. You pay for what you import

The package has one entry point per capability:

```ts
import { getFleet } from '@aephia/atlas-kit/fleets';
import { getStarSystem } from '@aephia/atlas-kit/world';
```

Importing `fleets` does not pull in `markets` or `crafting`. Bundle budgets for
every entry are enforced in CI, so this stays true.

The root entry (`@aephia/atlas-kit`) is the convenience client, which composes the
common capabilities. It is the largest import and the easiest to start with.
Reach for capability entries when bundle size matters.

## What this adds up to

Reads are explicit, results are trustworthy, and staleness is visible. The cost
is a little more ceremony than an SDK that hides its I/O — an extra `await`
where another library might give you a magic property.

Hiding network calls behind property access can make an application send many
RPC requests without making that traffic obvious in the code.

## Where to go next

- [How Atlas Kit changes the game](/start-here/how-it-acts/) — the same rules, for writes
- [The game map](/game-map/) — the gameplay concepts and what connects them
- [The API map](/map/) — the same universe from the SDK's side
- [Reference](/reference/) — every public entry, generated from source
- [For AI assistants](/ai/) — machine-readable docs, and the legacy-package trap
