Files
DartGame/README.md
T

4.5 KiB

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. 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.

NixOSconfiguration.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):

programs.git = {
  enable = true;
  lfs.enable = true;
};

Debian/Ubuntusudo apt install git-lfs macOSbrew install git-lfs

Then, once per machine:

git lfs install

Setup

git clone <gitea-url>/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.

Tooling

# GDScript formatter + linter
nix-shell -p gdtoolkit_4        # or: pipx install "gdtoolkit==4.*"

# Pre-commit hooks
pre-commit install

Open the project

Point Godot 4 at game/project.godot.


Where things live

Nextcloud This repo
.blend, .kra, .psd never
.glb, .png (exported) (LFS)
Code, scenes, .tres
Moodboards, references

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 maps each repo artifact back to its Nextcloud source.


Layout

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
├── content/official/   ← OUR CONTENT, loaded as a mod like any other
│   ├── skins/
│   ├── modifiers/
│   └── modes/
└── shared/             fonts, shaders

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.


Docs

Full documentation lives in the Obsidian vault at Nextcloud/DartGame/documentation/. Start with Build Plan.


Contributing

Branches: feat/, fix/, chore/ off main. main is protected and always runnable.

Commits: Conventional Commits.

feat(modding): add ModRegistry namespaced lookup
fix(scoring): ScorePacket.total() ignored final_override

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

⚠️ 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 a branch switch:

rm -rf game/.godot/

then Project → Reload Current Project. If it's 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.