# Projeto Novo Jogo — Handoff Briefing for Claude Code on Windows

> **How to use this file:** put it in the folder where the Unreal project will live, open Claude Code
> there, and say: *"Read HANDOFF.md and set up the project."* It contains everything decided so far —
> months of research and group decisions compressed into one page — so you don't have to re-derive it.
> After the project skeleton exists, `CLAUDE.md` (section 9) becomes the permanent project memory and
> this file can be archived.

---

## 1. What we are building

A **co-op PvE medieval fantasy game** for a private group of ten friends (older men, long-time friends,
mostly in Brazil; the host is in Barcelona). It is never sold, never public. Design was crowdsourced from
the group through a questionnaire and is documented at:

| Site | Contents |
|---|---|
| https://gamedesign.liztem.com | Design decisions, votes, class roster, session structure |
| https://gameengine.liztem.com | Technical research: engine, art styles, asset libraries, monster pipeline |
| https://gameengine.liztem.com/tasks | Production setup tasks |
| https://gameserver.liztem.com | Server/infrastructure plan, costs, security |
| https://gameserver.liztem.com/tasks | Infrastructure status (server is already live) |

Those pages are in Brazilian Portuguese (they are read by the group). Work with the human in English.

---

## 2. Locked decisions — do not reopen without the human

**Game shape**
- 5 to 10 players per session. Tune encounters for 5; scale spawns roughly linearly per extra player;
  reserve HP scaling (+20–30%/player) for bosses and elites; enemy damage growth ~+4%/player.
- **PvE only.** They play *together against the game*. No PvP, no traitor mechanics, no free-for-all.
- **Voice is Discord** (external). No in-game voice or text chat needed.
- **PC / Windows only**, installed client. Everyone has a good GPU.
- **Persistent progression** — server-authoritative, never client-side.
- **Medieval fantasy.**
- **One distinct fixed class per player**, specialising over time (10-class roster in section 5).
- Session model: a persistent **guild-hall hub** + **20–40 minute expeditions** chosen from a contract
  board, grouped into weekly 3-mission "Sagas".
- **Blessing / Curse cards**: every contract rolls 1 Blessing and 1–2 Curses that change the rules of the
  night; accepting Curses raises rewards 15–30%. This is the group's signature mechanic (proposed by
  TheKing; it mirrors Deep Rock Galactic's anomalies/warnings).
- Rejected by the group: quick 5–15 min matches, competitive leaderboards, mobile, neon art.

**Tech**
- **Unreal Engine 5.8**, C++ first. Blueprints only as near-empty leaf subclasses.
- **GAS (Gameplay Ability System)** as the backbone. ASC on **PlayerState** (Lyra pattern — survives
  respawns mid-expedition). One DataAsset per class. Blessings/Curses are GameplayEffects.
- **Dedicated Linux server** (never a listen server) — already running in AWS São Paulo.
- Persistence in **SQLite on the server**, backed up to S3.
- Art: **stylized low-poly painterly** ("painterly low-poly under cinematic light"), Synty POLYGON
  ecosystem, with UE 5.8's Substrate Toon shading available as an optional dial (experimental — keep a
  post-process cel-shader as fallback, never hard-depend on it). **Leave Substrate disabled in
  `DefaultEngine.ini` by default**: it is a T3 experiment, and the cel look must survive as a
  post-process path regardless of how that experiment goes.

**Still open (the group decides, not us)**
- Camera: third-person with generous zoom vs near-isometric. Resolve with a prototype, not an argument.
- Final look: soft-PBR vs toon-ramped — decided by screenshots of the same scene in both grades.
- Which friend takes which class; whether the 10th slot is Necromancer or Siege Crossbow.

---

## 3. Where things live (three machines)

```
WINDOWS PC (this machine)          AWS DEV MACHINE (Ubuntu, no GPU)      GAME SERVER (São Paulo)
UE 5.8 editor + project      →     infra, websites, automation      →    Linux dedicated server
Synty assets                       Claude Code sessions for infra        SQLite saves + backups
Claude Code for game code          publishes builds to S3                pulls builds from S3
        ↓ git + LFS                        ↑                                     ↑
        └─── github.com/willylazari/newgame (private) ───┘   s3://gameserver-liztem-builds/server/
```

The UE editor needs a GPU, so **the project lives here, on Windows**. The AWS machine handles servers and
websites. Never try to run the editor there.

**Infrastructure that already exists and works** (do not rebuild):
- Game server: `game.liztem.com` (EC2 m6a.large, sa-east-1, instance `i-00e93e1a19a61bd0f`), UDP port
  7777 only, SSM-only admin, no SSH. Currently runs a UDP echo placeholder.
- It **shuts itself down** after 30 idle minutes, with an 8-hour hard cap. Start/stop panel:
  https://gamepanel.liztem.com (password-protected).
- `/srv/game/bin/deploy-server.sh` on the server pulls a build from S3, keeps the previous version for
  rollback, and restarts `game-unreal.service`.
- Buckets: `gameserver-liztem-builds` (eu-west-1, private, versioned) and `gameserver-liztem-saves`
  (sa-east-1, private, versioned, 30-day retention).
- Cost is ~US$8/month parked, ~US$13/month while playing. Budget alarms fire at $20/$35/$40/$50, and a
  traffic-anomaly alarm auto-stops the instance. **Keep it that way** — this account had a $689 bot
  incident in the past, so no anonymous file serving, ever.

---

## 4. First tasks — what to build

In order. Stop and show the human after each one.

**T0. Prerequisites (human, interactive).** Account-gated installers, so Willy runs them:
- **Epic Games Launcher → UE 5.8**, and under *Target Platforms* tick **Linux**.
- **Visual Studio 2022** with the **Game development with C++** and **.NET desktop development**
  workloads. Without it there is no C++ toolchain on Windows and nothing compiles.
- **Linux cross-compile toolchain v26 (clang-20.1.8)** — Epic names this exact version for UE 5.7–5.8:
  `https://cdn.unrealengine.com/CrossToolchain_Linux/v26_clang-20.1.8-rockylinux8.exe`
  **Verification step that saves an afternoon:** after installing, run `echo %LINUX_MULTIARCH_ROOT%`.
  If it is empty, the Linux target silently does not appear in the build configurations — that is the
  single most common failure mode here. The toolchain is version-locked to the engine: moving off 5.8
  later means re-checking Epic's Linux requirements page, never reusing v26 blindly.

**Agent tooling** — full setup, with the gotchas, is in **`TOOLING.md`** shipped alongside this file. The two that matter most (both first-party, verified):
- **Epic's own Claude Code plugin**: `/plugin install unreal-engine-skills-for-claude-code@claude-plugins-official`.
  It talks to the editor's built-in MCP server and exposes hundreds of tools across 30+ toolsets —
  GAS state inspection, gameplay tags, C++ automation tests, Blueprints, materials, Niagara, screenshots,
  log inspection. In the `.uproject` Plugins array enable **both** `ModelContextProtocol` and
  `AllToolsets` — AllToolsets is off by default and without it the server starts with **zero tools**.
- **clangd-lsp**: `/plugin install clangd-lsp@claude-plugins-official` plus `winget install LLVM.LLVM`.
  Real go-to-definition and compiler diagnostics over UE headers instead of grep. Generate
  `compile_commands.json` from UBT; restrict the index to `Source/` and `Plugins/` — indexing all of
  `Engine/` will thrash the machine.

**T1. Project skeleton.** New **C++** project (no template), name `NewGame`. Enable plugins:
GameplayAbilities, EnhancedInput, ModularGameplay.

*Modules* (in `Source/`): `NewGame` (runtime) and optionally `NewGameEditor` (editor-only helpers).

*Targets* — **three** `.Target.cs` files, and they are not the same thing as modules. The dedicated-server
package in section 8 has nothing to build without the third one:
- `NewGame.Target.cs` — `TargetType.Game`
- `NewGameEditor.Target.cs` — `TargetType.Editor`
- `NewGameServer.Target.cs` — `TargetType.Server` ← the one that feeds São Paulo

```csharp
// Source/NewGameServer.Target.cs
using UnrealBuildTool;

public class NewGameServerTarget : TargetRules
{
    public NewGameServerTarget(TargetInfo Target) : base(Target)
    {
        Type = TargetType.Server;
        DefaultBuildSettings = BuildSettingsVersion.Latest;
        IncludeOrderVersion = EngineIncludeOrderVersion.Latest;
        ExtraModuleNames.Add("NewGame");
    }
}
```

Then drop in `CLAUDE.md`, `.gitattributes`, `.gitignore` and `PROGRESS.md` (section 9), `git init`,
`git lfs install`, first commit.

**T2. GAS foundation.** Follow the Narxim-GAS-Example pattern (github.com/Narxim/Narxim-GAS-Example):
AbilitySystemComponent on PlayerState, one AttributeSet, an AbilitySet-style `UPrimaryDataAsset` per
class. Create the 10 class DataAssets as empty-but-named files so the roster is visible in the repo.
GameplayTags go in `Config/DefaultGameplayTags.ini` — never invented ad hoc in code.

**T3. The glade test** (this settles an open group decision). Build one small Synty scene — the Meadow
Forest biome with a shrine, a couple of characters — and render it **twice**: once as soft PBR
("mini-Valheim") and once with a toon ramp ("mini-BotW"). Same assets, same camera, same time of day.
Export two screenshots for the group to vote on in Discord.

**T4. Ten capsules on the real server.** Networked movement for 10 players against the actual dedicated
server in São Paulo, with both candidate cameras toggleable. This retires the UDP echo placeholder and
answers the camera question with evidence. Note the host plays from Barcelona at ~200 ms — verify it
feels acceptable, because the whole architecture assumes it does.

**T5. First expedition.** One short mission with one Blessing, one Curse, and a mediocre boss for ten
grown men to embarrass themselves against.

---

## 5. The 10-class roster (proposed, group still claiming seats)

| Class | Group job |
|---|---|
| Bulwark (knight) | Tank/anchor: taunts, deployable pavise wall, holds chokepoints |
| Chirurgeon | Heals, fastest revives, cleanses. Helpful, never mandatory |
| Huntsman | Marks elites for bonus team damage, counters specials |
| Sapper | Barricades, deployable ballista, bridges and breaches |
| Stormcaller | Crowd-clear: AoE bursts that delete hordes |
| Herald (bard) | Buff auras, stamina/cooldown tempo, rally, fear-break |
| Beastwarden | Pet off-tank, tracks hidden caches (serves the exploration vote) |
| Shadowblade | Single-target boss killer, locks, traps, fast objectives |
| Alchemist | Oil and frost fields that combo with Stormcaller's fire; throwables |
| Arbalest *or* Necromancer | Siege crossbow: huge single-target, deliberately low APM — or a
  summoner. Group decides. |

**Coverage rule:** damage, sustain and control must each live in at least three classes, so any five-player
subset is viable. No class is mandatory.

**Progression, three layers:** (1) a lean 2-branch talent tree per class; (2) **performance medals** — XP
for doing your class's job well (heal that prevented a down, mark that became a kill), guarded against
farming: only team-outcome actions score, capped per match, with flat mission XP still the majority;
(3) DRG-style ceremonial promotions at cap.

---

## 6. Code conventions (non-negotiable)

**Everything that matters lives in text an AI can read.** Printing "hello" is ~8,000 characters of
Blueprint clipboard versus 14 of C++, and `.uasset` is binary that cannot be diffed or reviewed.

- All gameplay logic in **C++** under `Source/`.
- Blueprints only to wire mesh/montage/VFX in a leaf subclass, named `BP_` + the C++ class name.
- GameplayTags in `Config/DefaultGameplayTags.ini`.
- Class/ability/monster data in **DataAssets + committed CSV/JSON**.
- **Art packs are never committed.** Masters live outside the repo on Windows; the mirror is
  `s3://gameserver-liztem-assets` (private, versioned). GitHub's free LFS allowance is 1 GiB and the
  first Synty batch is 5.1 GB — LFS is a safety net for one-off assets, not the storage plan.
  Never commit `Binaries/`, `Intermediate/`, `Saved/`, `DerivedDataCache/`.
- Use `CharacterMovementComponent`, **not** the experimental Mover plugin — it replicates properly for
  5–10 players.
- Lyra is a **pattern quarry, never a fork**: copy the idea, not the files.
- Enemy AI: Behavior Trees for grunts, StateTree for boss phases. Cap concurrent enemies at ~40–60 and
  use significance-based tick throttling. Do not adopt Mass/MassAI.
- The server is the authority on everything that persists. The client never writes a save.

---

## 7. Assets

**SyntyPass subscription** (active) gives the entire 130+ pack library, Unreal versions. Always download
the **Unreal** build of each pack, not Unity.

First batch (enough for T1–T4): **POLYGON Fantasy Kingdom** (the spine — 2,100+ prefabs, modular castle
and houses with enterable interiors), **POLYGON Meadow Forest — Nature Biome** (the glade test),
**POLYGON Modular Fantasy Hero Characters** (class bases).

Second batch: **Fantasy Village** (the guild hall), **Fantasy Rivals** (20 large creatures plus a "big
rig for massive monsters" — this is the boss bench), **Dungeon Realms**, the **Sidekick** modular packs
(Fantasy Knights / Villagers / Skeletons / Goblin Fighters — modular means effectively unlimited horde
variety), **INTERFACE Dark Fantasy HUD + Menus** (the whole UI).

Free from Fab (same Epic account): **Game Animation Sample** (500+ AAA animations with motion matching),
Paragon characters, Infinity Blade medieval props.

Paid plugins to buy only when combat starts (~$75 total): **GAS Companion** ($24.99) and **Combo Graph**
($49.99) — verify the 5.8 build exists before buying Combo Graph.

**Do not buy** Infinity PBR monsters, Tidal Flask packs, or a UI kit — the subscription already covers
all three, and mixing vendors costs coherence. A style-unifying palette LUT plus one strong lighting
direction is what makes this art direction work; that is where the effort goes, not texture resolution.

---

## 8. Build and deploy

```bash
# Editor build (from the project folder, Git Bash)
"C:/Program Files/Epic Games/UE_5.8/Engine/Build/BatchFiles/Build.bat" NewGameEditor Win64 Development \
  -Project="$PWD/NewGame.uproject" -WaitMutex

# Automated tests
UnrealEditor-Cmd.exe NewGame.uproject -ExecCmds="Automation RunTests Projeto; Quit" -unattended -nullrhi -log

# Package the Linux dedicated server (needs Epic's Linux cross-compile toolchain installed)
RunUAT.bat BuildCookRun -project="$PWD/NewGame.uproject" -platform=Linux -server \
  -serverconfig=Development -cook -stage -pak -archive -archivedirectory="$PWD/Builds"

# Ship it: tar the archived server folder, then
aws s3 cp servidor.tar.gz s3://gameserver-liztem-builds/server/latest.tar.gz --region sa-east-1
# then on the game server (via SSM, from the AWS dev machine):
/srv/game/bin/deploy-server.sh
```

If the AWS CLI is not configured on Windows, hand the tarball to the AWS dev machine and let the Claude
session there publish and deploy it — that machine already has the permissions and the SSM path.

---

## 9. Files that ship with this handoff

The whole set is also downloadable as one zip:
**https://gameengine.liztem.com/tpl/newgame-setup.zip**

Individually — fetch by exact URL, since **the `/tpl/` directory itself returns 404 on purpose**. Nothing on
these servers is anonymously browsable (see the bot-incident note in section 3), so there is no index to
list; that is correct behaviour, not a broken link.

- https://gameengine.liztem.com/tpl/CLAUDE.md — the permanent project memory (locked decisions,
  conventions, commands). Put it at the project root; Claude Code reads it automatically every session.
- https://gameengine.liztem.com/tpl/.gitattributes — Git LFS rules, kept as a safety net for one-off
  assets (see the asset-storage rule above: vendored packs go to S3, not git).
- https://gameengine.liztem.com/tpl/.gitignore — Unreal's generated folders.
- https://gameengine.liztem.com/tpl/PROGRESS.md — the progress log template (see section 10).
- https://gameengine.liztem.com/tpl/TOOLING.md — agent tooling setup: Epic's Claude Code plugin,
  clangd, UE skills, **concept-art generation on this machine**, the git remote, and how to publish
  builds. Read it right after this file.
- `scripts/concept-art.py` and `skills/monster-pipeline.md` (both in the zip).

---

## 10. Reporting progress — keep the task board honest

The production task board lives at **https://gameengine.liztem.com/tasks** (Portuguese, because the group
reads it). It currently lists tasks T1–T5 as "waiting on me". **Whenever you finish one of them, say so
explicitly** so the board stops lying.

Two mechanisms, use both:

1. **Keep `PROGRESS.md` at the project root updated.** One line per task: what got done, the date, and any
   decision that was forced along the way (e.g. "T3 done — group picked the toon grade"). Commit it. The
   AWS dev machine reads the repo, so this is how the other Claude session learns what happened here
   without anyone re-typing it.
2. **Tell the human in your closing message**: "T2 is done — ask the AWS session to update
   gameengine.liztem.com/tasks". He relays it, and the board is updated there (the websites live on that
   machine, not this one).

Also worth reading before you start, and updating the same way if reality diverges:
- https://gameserver.liztem.com/tasks — infrastructure status (server is live and rehearsed)
- https://gamedesign.liztem.com — the group's design decisions and what is still open

If something in this handoff turns out to be wrong once you are inside the engine — a command that does
not work, an assumption that does not hold, a plugin that has no 5.8 build — **say so plainly**. The
documents get corrected; nobody defends a stale plan here.

---

## 11. What not to do

- Do not put gameplay logic in Blueprints "just to test quickly" — it never comes back out.
- Do not fork Lyra.
- Do not add a plugin that hides its logic in binary assets; it blinds the agent workflow.
- Do not mix asset packs from different visual schools without the palette/LUT pass.
- Do not write saves on the client, and do not let the server trust client-reported progression.
- Do not open ports on the game server. Admin happens through SSM.
- Do not serve any project file anonymously from a web server or bucket.
- Do not commit API keys. Secrets go to AWS SSM SecureString (that is the established pattern here).
