Files
DartGame/README.md

192 lines
5.7 KiB
Markdown

# DartGame
A 3D darts game where the core loop is **dragging modifiers onto board sectors** to create
compounding scoring interactions. Balatro's joker system, applied to a dartboard.
Built in **Godot 4.7**. Modding is a first-class concern, not an afterthought — our own content
ships through the same loader community mods will use.
---
## ⚠️ Install `git-lfs` BEFORE you clone
Clone without it and you'll get **130-byte text pointers** where your textures and models
should be. Godot will throw import errors that look completely baffling and you will lose an
hour.
**NixOS** — Home Manager (also writes the LFS filter config, so a fresh machine is correct with
no imperative step):
```nix
programs.git = {
enable = true;
lfs.enable = true;
};
```
Or system-wide:
```nix
environment.systemPackages = with pkgs; [ git git-lfs ];
```
**Debian/Ubuntu**`sudo apt install git-lfs`
**macOS**`brew install git-lfs`
Then, once per machine:
```bash
git lfs install
```
---
## Clone
```bash
git clone ssh://git@gitea.lilpenn.org:30009/ced/DartGame.git
cd DartGame
```
> **Note the `git@`.** Without it, SSH tries to log in as your local username and you get
> `Permission denied (publickey)`. Gitea's SSH user is always `git`.
### Verify LFS worked
```bash
file game/core/board/dartboard.glb
```
**Want:** `glTF binary model, version 2, length 3302888 bytes`
**Bad:** `ASCII text` ← that's an unfetched LFS pointer. Stop and fix it before opening Godot.
---
## Setup
```bash
# GDScript formatter + linter
nix-shell -p gdtoolkit_4 # or: pipx install "gdtoolkit==4.*"
# Pre-commit hooks
pre-commit install
```
Then point Godot 4 at `game/project.godot`.
---
## Where things live
| | Nextcloud | This repo |
|---|---|---|
| `.blend`, `.kra`, `.psd` | ✅ | ❌ **never** |
| `.glb`, `.png` (exported) | ❌ | ✅ (LFS) |
| `.res` (collision shapes) | ❌ | ✅ (LFS) |
| Code, scenes, `.tres` | ❌ | ✅ |
| Moodboards, references | ✅ | ❌ |
| **Documentation** | ✅ | ❌ |
Source files live in the **company Nextcloud share**, not here. They churn constantly, never
merge, and 99% of their revisions have no corresponding code change — they'd bloat LFS history
forever, on every clone.
Exported artifacts **do** live here, because they must version in lockstep with the code that
references them. If a UV layout changes and a script needs updating, those belong in one commit.
[`SOURCES.md`](SOURCES.md) maps each repo artifact back to its Nextcloud source.
---
## Layout
```
game/
├── core/ ← THE ENGINE. Contains zero game content. Ever.
│ ├── board/ dartboard scene, mesh, 21-slot logic, trimesh collision
│ ├── dart/ dart scene, drag/throw/flight physics
│ ├── modding/ mod registry, modifier base class
│ └── ui/ drop catcher, modifier tray, sector swatch
├── content/official/ ← OUR CONTENT, loaded as a mod like any other
│ ├── mod.json
│ ├── skins/ bulls/ · sectors/ · flat_tire/
│ └── modifiers/ (empty — Phase 5)
└── scenes/ main.tscn, camera_3d.gd
```
### The two rules
**1. Nothing in `core/` knows about any specific content.**
About to write `if modifier.id == "mjolnir"` in `core/`? Stop — you need a new primitive.
**2. `content/official/` must be deletable.**
Delete it, and the game boots to an empty state without crashing. That's the proof the mod
pipeline is real. If it can't, we don't have a mod system — we have a plugin folder.
---
## The board is 21 slots
`dartboard.glb` exports 21 material slots: `sector_1``sector_20`, plus `bulls`. Each sector
is its own material, so it can be skinned and modified independently.
Hit detection reads the **mesh face index** from the raycast and maps it to the material name —
*not* an angle. That's what lets a modifier rotate or remap the board and still score correctly.
Full detail in the docs.
---
## Docs
Full documentation is an Obsidian vault at `Nextcloud/DartGame/documentation/`.
**Start with `Build Plan`.** Then `Conventions` before your first commit.
| Note | |
|---|---|
| **Build Plan** | What we're building. Eight phases, current status. |
| **Conventions** | Naming, git workflow, linting. **Read before your first commit.** |
| **Architecture** | How the engine works and why. |
| **Godot Gotchas** | Every trap that cost us time. Read it. |
| **Modding** | The mod format and public API. |
| **Asset Pipeline** | Nextcloud ↔ repo handoff, Blender export settings. |
| **File Tree** | Full directory reference. |
---
## Contributing
**Branches:** `feat/`, `fix/`, `chore/` off `main`. `main` is protected and always runnable.
**Commits:** Conventional Commits.
```
feat(modding): add ModRegistry namespaced lookup
fix(board): face-to-slot map missed the last surface
```
**Before you open a PR:**
- [ ] `gdformat --check game/` passes
- [ ] `gdlint game/` passes
- [ ] Nothing in `core/` references a specific content ID
- [ ] If an asset changed: source updated in Nextcloud, `SOURCES.md` current
- [ ] `git lfs status` shows binaries as LFS
### ⚠️ Moving files
**Commit first.** Godot's refactoring is fragile. Move files from **inside the Godot editor's
FileSystem dock**, never your file manager, so references get fixed up.
If things break after a move or branch switch:
```bash
rm -rf game/.godot/
```
then Project → Reload Current Project. Worse than that? `git restore .` — which only works if
you committed first.
---
## Status
**Pre-alpha.** Phase 0 (repo hygiene) complete. Phase 1 (skeleton) in progress — board and dart
scenes exist with collision; the throw mechanic is still being tuned.
See `Build Plan` in the docs vault.