Updated

Dot for Godot

The Dot collection — fifty open-source Godot 4 addons, a launcher, a server tool and five reference games that add identity, content delivery, netcode, dedicated servers, a player layer and a genre kit on top of stock Godot.

Dot is The Modding Community’s collection of Godot 4 assets: fifty-six addons, a shell launcher, a server tool, and eight games and packs that exist to run the addons together. They are on the site as the Dot assets collection.

Two GitHub accounts, and the split is a rule rather than an accident. The addons are the organisation’s — modcommunity/dot-* — and the games are their author’s, under gamemann. A project’s name says what it is, not who owns it, so dot-bootstrap’s projects.tsv writes the clone URL out per line rather than deriving it. That file is the only copy of the list, and bootstrap --check fails if it and the disk disagree.

They add the parts of a game platform that are not engine features — accounts, avatars, content delivery, netcode, dedicated servers, moderation, timers, leaderboards — as layers above stock Godot. A game that wants none of it stays an ordinary Godot project.

Getting started

From nothing to a Dot game running on your machine, and then to a server other people can join.

The addons

All fifty, what each is for, and every hook it exposes.

Hosting a server

./setup.sh, the YAML, roles instead of flags, votes, the container, and the site listing.

Conventions

The rules every addon obeys: no autoloads, DotResult, DotNodeRef, layered configuration, and why the browser decides half of them.

How the collection is organised

Foundation dot-core. The only hard dependency.
The player dot-player, dot-player-controller, dot-player-char, dot-player-class, dot-physics, dot-spawn, dot-team. Who is in the session, what drives them, how big they are, which side they are on.
Identity and content dot-auth, dot-user, dot-user-avatar, dot-platform, dot-cloud. Who a player is, what they look like, and how they get content.
Servers and the wire dot-net, dot-server, dot-server-query, dot-server-security, dot-browser, dot-peer-to-peer, dot-moderation, dot-chat, dot-voice, dot-spectate, dot-vote.
The fight dot-combat, dot-weapon, dot-effects, dot-loadout, dot-inventory, dot-economy, dot-match, dot-objective, dot-2d.
The world dot-npc, dot-npc-ai, dot-npc-ai-director, dot-vehicle, dot-map, dot-props, dot-procedural-generation.
Progression dot-timer, dot-leaderboard, dot-stats, dot-achievements.
The person at the keyboard dot-ui, dot-settings, dot-console, dot-audio, dot-fx, dot-lighting.

Only dot-core is ever a hard dependency

In GDScript, a script that so much as mentions a class_name the project does not have fails to parse, and takes every script that references it down with it. An addon that imported another would therefore make that other addon mandatory for everybody.

So everything else is discovered at run time, duck-typed, or bridged by the game:

  • dot-server finds dot-auth and dot-cloud through DotRegistry and imports neither.
  • dot-net needs only dot-core and moves bytes through a Callable.
  • dot-player-controller, dot-combat, dot-loadout, dot-match and dot-2d each ship a *NetSync class describing what to replicate as data — property and type names as strings, which a bridge resolves. None of them names a dot-net identifier.
  • dot-browser implements dot-server’s wire format a second time rather than importing it, and checks itself against bytes dot-server’s encoder produced.
  • dot-team reaches dot-spectate, and dot-weapon reaches dot-loadout and dot-inventory, entirely by duck typing.

Four addons are the exception and each says so: dot-npc-ai and dot-npc-ai-director need dot-npc, and dot-player-controller, dot-player-char and dot-player-class need dot-player.

Duplication here is deliberate

Where two addons hold the same twenty lines, that is the rule above being paid for. Deduplicating it into a shared import is how one addon becomes a dependency of another.

How the pieces stack
                        ┌──────────────┐
                        │   dot-core   │  logging, capabilities, paths,
                        │              │  node refs, config, jobs,
                        └──────┬───────┘  transports, HTTP
      ┌───────────┬────────────┼────────────┬───────────┬──────────┐
      ▼           ▼            ▼            ▼           ▼          ▼
┌───────────┐ ┌──────────┐ ┌─────────┐ ┌──────────┐ ┌────────┐ ┌────────┐
│ dot-cloud │ │ dot-auth │ │ dot-net │ │dot-server│ │ dot-ui │ │ dot-2d │
└─────┬─────┘ └────┬─────┘ └─────────┘ └────┬─────┘ └────────┘ └────────┘
      │            │                        │
┌─────┴─────┐ ┌────┴───────────┐    ┌───────┴────────┐
│ dot-user  │ │dot-user-avatar │    │  dot-platform  │
└───────────┘ └────────────────┘    └────────────────┘

      ┌──────────────────┬───────────────┬──────────────┐
      ▼                  ▼               ▼              ▼
┌────────────┐    ┌──────────────┐ ┌───────────┐ ┌───────────────┐
│ dot-combat │    │ dot-loadout  │ │ dot-match │ │ dot-objective │
│ dot-weapon │    │ dot-inventory│ │           │ │ dot-spectate  │
│ dot-effects│    │ dot-economy  │ │           │ │               │
└────────────┘    └──────────────┘ └───────────┘ └───────────────┘
 what you hold     what you can      the round     what it is about,
                   afford now        itself        and who watches

the player layer, needing only dot-core under dot-player:

┌────────────┐ ┌──────────────────────┐ ┌─────────────────┐ ┌────────────────┐
│ dot-player │ │dot-player-controller │ │ dot-player-char │ │dot-player-class│
└─────┬──────┘ └──────────────────────┘ └─────────────────┘ └────────────────┘
      └──── every one of the three to its right needs it, and nothing else

┌──────────────┐ ┌──────────────┐ ┌────────────┐   all three need only
│ dot-physics  │ │  dot-spawn   │ │  dot-team  │   dot-core; dot-team
└──────────────┘ └──────────────┘ └────────────┘   duck-types dot-spectate

the ones that belong to the PERSON rather than to the server:

┌──────────────┐ ┌─────────────┐ ┌───────────┐ ┌────────┐ ┌────────────────┐
│ dot-settings │ │ dot-console │ │ dot-audio │ │ dot-fx │ │dot-peer-to-peer│
└──────────────┘ └─────────────┘ └───────────┘ └────────┘ └────────────────┘

      └──────────────────┴──────────────┴─────────────┘
                               │  every one of these needs
                               ▼  ONLY dot-core
                    ┌──────────────────────┐
                    │   your game          │  the bridges live here
                    └──────────────────────┘

The arrows are optional relationships everywhere except the top row. Read them as “works better with”, not “requires”.

We are not forking Godot

A fork means owning the engine’s release cadence, its export templates for six platforms, its web build, and every rebase for ever — and the moment it diverges, a game written for it cannot use anything from the Godot asset library. The parts of a platform people actually mean are not engine features: identity, avatars, content delivery, dedicated servers, moderation, discovery. Every one of those is a layer above an engine.

So: stock Godot, plus addons, plus one open backend protocol.

Why there is a genre kit

A general-purpose addon family gives nobody a reason to be the first person on a new platform. A genre does, and the one chosen is surf and bunny-hop: the movement is the hardest part to get right, a community in that genre is a server (a rotation, a records table, an admin who zones maps), its content is made and traded by players, and it is small enough to finish.

That is what dot-timer, dot-map, dot-vote and game-g2gfast are for, and why dot-player-controller reproduces classic strafe acceleration closely enough that somebody who has surfed for ten years does not feel the difference.

Licensing

The addons, the games and the tooling are MIT licensed and open source. The one thing that is not is the web back-end infrastructure — TMC’s own deployment. Every addon that talks to it does so over a documented HTTP protocol and points at a backbone_url you can change, so a project that wants its own backend builds one and changes a setting.