Fix sector drag and drop

This commit is contained in:
Johan Sandoval
2026-07-15 20:40:43 -05:00
parent 69f2028ce3
commit c221ec6c2a
12 changed files with 564 additions and 345 deletions
+79 -48
View File
@@ -3,24 +3,19 @@
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**. Modding is a first-class concern, not an afterthought — our own
content ships through the same loader community mods will use.
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 figuring out why.
should be. Godot will throw import errors that look completely baffling and you will lose an
hour.
**NixOS**`configuration.nix`:
```nix
environment.systemPackages = with pkgs; [ git git-lfs ];
```
Or declaratively via Home Manager (also writes the LFS filter config, so a fresh machine is
correct with no imperative step):
**NixOS**Home Manager (also writes the LFS filter config, so a fresh machine is correct with
no imperative step):
```nix
programs.git = {
enable = true;
@@ -28,6 +23,11 @@ programs.git = {
};
```
Or system-wide:
```nix
environment.systemPackages = with pkgs; [ git git-lfs ];
```
**Debian/Ubuntu**`sudo apt install git-lfs`
**macOS**`brew install git-lfs`
@@ -38,19 +38,28 @@ git lfs install
---
## Setup
## Clone
```bash
git clone <gitea-url>/DartGame.git
git clone ssh://git@gitea.lilpenn.org:30009/ced/DartGame.git
cd DartGame
git lfs pull
```
**Verify LFS worked.** Open `game/core/board/dartboard.glb` in a text editor. If it's
readable text starting with `version https://git-lfs...`, LFS did **not** run. Stop and fix
it before opening the project.
> **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`.
### Tooling
### 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
@@ -60,9 +69,7 @@ nix-shell -p gdtoolkit_4 # or: pipx install "gdtoolkit==4.*"
pre-commit install
```
### Open the project
Point Godot 4 at `game/project.godot`.
Then point Godot 4 at `game/project.godot`.
---
@@ -72,18 +79,19 @@ Point Godot 4 at `game/project.godot`.
|---|---|---|
| `.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.
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.
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` maps each repo artifact back to its Nextcloud source.
[`SOURCES.md`](SOURCES.md) maps each repo artifact back to its Nextcloud source.
---
@@ -92,18 +100,15 @@ one commit.
```
game/
├── core/ ← THE ENGINE. Contains zero game content. Ever.
│ ├── board/ dartboard scene, mesh, sector logic
│ ├── dart/ dart scene, physics
│ ├── scoring/ ScorePacket pipeline
── game/ GameContext ← the mod API
│ ├── modding/ loader, registry, base classes, primitives
│ ├── ui/ modifier tray, drag-and-drop
│ └── debug/ hit_simulator.tscn ← you'll use this daily
│ ├── 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
│ ├── skins/
│ ├── modifiers/
│ └── modes/
└── shared/ fonts, shaders
│ ├── mod.json
│ ├── skins/ bulls/ · sectors/ · flat_tire/
│ └── modifiers/ (empty — Phase 5)
└── scenes/ main.tscn, camera_3d.gd
```
### The two rules
@@ -117,10 +122,33 @@ pipeline is real. If it can't, we don't have a mod system — we have a plugin f
---
## 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 lives in the Obsidian vault at
`Nextcloud/DartGame/documentation/`. Start with **Build Plan**.
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. |
---
@@ -131,30 +159,33 @@ Full documentation lives in the Obsidian vault at
**Commits:** Conventional Commits.
```
feat(modding): add ModRegistry namespaced lookup
fix(scoring): ScorePacket.total() ignored final_override
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
- [ ] New content is one self-contained folder
- [ ] 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.
**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 a branch switch:
If things break after a move or branch switch:
```bash
rm -rf game/.godot/
```
then Project → Reload Current Project. If it's worse than that, `git restore .` — which only
works if you committed first.
then Project → Reload Current Project. Worse than that? `git restore .` — which only works if
you committed first.
---
## Status
**Pre-alpha.** Currently in Phase 0 (repo hygiene). See [`docs/build_plan.md`](docs/build_plan.md).
**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.