Extension points

Every place a game plugs into the Dot collection — the abstract classes to subclass, the Callables to assign, the resources to author, the registry names to publish under, and the settings to layer.

Nothing in the collection should require a fork. A change that makes one of the points below harder to reach is treated as a regression even when every test still passes.

There are five kinds of extension point, and knowing which kind you are looking at tells you where to look for it.

Subclass a base class

An abstract class with a documented set of _-prefixed methods to override. Stores, sources, codecs, rules, screens, modules. Roughly thirty of them.

Assign a Callable

A field on a node, usually named *_fn or *_source, that answers one question the addon deliberately cannot answer itself: where a player is, which team they are on, where bytes go. About fifty.

Author a Resource

A .tres a designer edits in the inspector: tunables, schemas, catalogues, rules, styles, surfaces. No code at all.

Publish under a registry name

Duck-typed seams. Register an object with one method under an agreed name and two addons cooperate without either importing the other.

Layer a setting

Every DotConfig: exported defaults, then a JSON or YAML file, then the environment, then the command line.

The whole index

To change Where
Which node a component attaches to DotNodeRef on every component
Content sources (CDN, disk, in-band) DotCloudSource subclass
How a player authenticates (Steam, Epic, your own) DotAuthProvider subclass, DotAuthServer.add_provider
Where bans live (shared DB, HTTP service) DotBanStore subclass on DotBanManager
Site groups → server permissions DotAuthAdminSource, or any object with lookup() / source_name()
Server commands and behaviour DotModule subclass, or DotConsole.command
What a server query reports about the game DotQueryProvider subclass on dot_query_source, or DotModule.add_query_provider
What a server punishes, and how far it escalates DotSecurityRule documents, in JSON or built in code
Where a server reads ban lists from DotBanFeed entries on DotBanFeeds, chained onto dot_ban_source
Whether a movement claim is possible DotAntiCheat.movement_reference, a Callable that re-simulates one tick
How a world is lit, and how much of it this machine draws DotLightDocument and DotLightProfile, applied by DotLightRig
Reacting to or vetoing anything DotEventBus.hook_pre / hook_post
What replicates, and how precisely DotNetVar declarations; Type.CUSTOM for any type
Simulation, controls, messages DotNetBehaviour, DotNetInput, DotNetMessage subclasses
Who sees what DotNetInterest subclass
How entities are constructed DotNetSpawner.register_factory
Where bytes go DotNetManager.send_fn, DotTransport subclass
Where voice comes from or goes DotVoiceSource / DotVoiceSink subclass
The voice codec DotVoiceCodec subclass, DotVoiceCodec.register
Who hears whom on voice DotVoiceRouter.team_fn / position_fn / listener_filter
Who may speak at all Anything with is_voice_muted(peer) under dot_mute_source
Where punishments live DotPunishmentStore subclass
Which database holds them DotSqlDriver subclass, or DotPunishmentStoreRest
How a peer maps to a person DotModerationManager.key_for_peer
Whose ban list a server enforces anything registered as dot_ban_source
How many clients one address may hold sv_max_connections_per_ip, DotAddressGuard
How a moderator names a player DotServer.find_sessions — name, username, id, ip:, @me
Where a player is, and how to move them DotModTools.position_fn / teleport_fn
What happens when a player joins DotPlatformModule, or DotPlatformHub.admit directly
Where entitlements come from DotPlatformHub.entitlement_source
Where profiles live DotUserStore subclass on DotUserManager
What a name may be DotUserManager.name_filter
What a player may wear DotAvatarSchema + DotAvatarEntitlements
Where avatars live DotAvatarStore subclass
How a part id becomes an asset DotAvatarCatalogue.resolver
Movement feel DotFpsTunables, per instance or per JSON file
A named variation on it — sideways, low gravity, prebhop DotFpsStyle + DotTimerStyle, paired by id
How one kind of ground behaves DotFpsSurface in a DotFpsSurfaceSet
A temporary change — speed pad, stun, launcher DotFpsModifier
A whole new way to move — ladder, water, grapple DotFpsMoveMode subclass
What the player collides against DotFpsBody subclass, via DotFpsController._make_body
Input devices, bots, demo playback DotFpsSampler / Dot2DSampler, or build a command yourself
What a timer reacts to in the world DotTimerZone.Kind, drawn in the editor or with DotTimerZonePainter
Where records and leaderboards live DotTimerStore / DotLeaderboardStore subclass
What a map is, and what plays next DotMapDef in a catalogue; DotMapRotation, DotMapVote
How a map change reaches clients DotMapSyncHost.send_fn / DotMapSyncClient.send_fn
What a client will load on a host’s say-so DotMapSyncClient.accept_unknown_maps
Every policy in a vote DotVoteRules, 55 settings, layered like every DotConfig
What can be voted for, and what “play this” means DotVoteSource subclass, or DotVoteGameSource / DotVoteMapSource / DotVoteListSource
Who counts as a player, an admin or a spectator in a vote DotVoteDirector.player_count_fn / is_admin_fn / is_spectator_fn
What one player’s vote is worth DotVoteDirector.weight_fn
What the vote’s commands are called DotVoteCommands.prefix / names
What can be spawned, and how much of it DotPropCatalogue, DotPropLimits
A new sandbox tool, or a weapon DotPropTool subclass
A prop that has code DotPropDef.meta.script, a PATH
What a weapon is DotWeapon, and DotDamageType for how it hurts
Where a shot goes DotTrace subclass — DotTracePhysics or DotTraceFlat
Named body regions and their multipliers DotHitGroup, a table rather than an enum
Friendly fire, self damage, clamping DotDamageRules, plus DotDamageResolver.adjust
Turning lag compensation on DotCombatManager.rewind_fn / restore_fn, two callables
What an item is, and what fits where DotItem, DotLoadoutSlot, DotLoadoutSchema
Where loadouts live DotLoadoutStore subclass
What winning means DotMatchRules subclass — _round_outcome, _round_winner
Where players appear DotSpawnPoint, DotSpawnSelector.danger_fn / filter_fn
What a screen is DotScreen subclass, registered with a DotScreenStack
What the interface looks like Theme, or DotUiTheme’s palette. dot-ui ships no art
How a settings screen is built Nothing: DotSettingsPanel reads your DotConfig
How a 2D thing moves Dot2DTunables, and Dot2DMassRules for a mass-based game
What a 2D thing collides against Dot2DBody subclass
Long work without blocking a frame DotJob subclass on a DotScheduler
Where log records go DotLogSink, or DotLog.add_sink with a Callable

Subclass points, by addon

Each of these is an abstract base with a small, documented set of methods. The ones marked must have no useful default.

DotTransportdot-core

_create_server, _create_client, _transport_name, _is_available, supports_web_clients, scheme. _is_available is checked before use, so the failure is “this build cannot host over ENet” at boot rather than a null peer three calls later.

DotJobdot-core

_step (a bounded slice; return true if more remains), _progress (0..1, or -1 for genuinely unknown — an honest indeterminate bar beats one that jumps backwards), _setup, _teardown, is_thread_safe.

DotConfigdot-core

env_prefix, cli_prefix, sensitive_keys, validate.

DotLogSinkdot-core

A record handler. DotLog.add_sink(callable) is the one-liner version.

DotCloudSourcedot-cloud

source_name, is_supported, can_serve(manifest), fetch. A fetch must write to DotCloudStore.partial_path, resume from partial_size where it can, and finish through commit_partial — which is the only place the hash is verified. Writing into the object directory directly is how unverified content gets mounted.

DotAuthProviderdot-auth

_provider_name, _handles(credential) (cheap and purely structural), _authenticate(credential), _validate. A provider that claimed a credential and then rejected it has made a decision — the server does not fall through to another one.

DotNetBehaviourdot-net

_register_net_vars, _net_ready, _net_removed, _net_simulate, _net_state_applied, _net_interpolated, _net_read_property, _net_write_property. The class a game subclasses most.

DotNetInputdot-net

_write, _read, _sanitise (clamps anything a client could exaggerate — quantisation bounds each field, this is for the relationships between them), _equals for redundancy suppression.

DotNetMessagedot-net

_type_name (namespaced; yours should not start with net.), _write, _read, _validate. Validate in _validate, not in the handler — a handler that validates is a handler somebody copies without the validation.

DotNetInterestdot-net

_is_relevant (override this and nothing else for most strategies), _candidates for a bulk filter, _prepare to rebuild an index once per snapshot, _score for prioritisation under a tight budget.

DotModuledot-server

_module_name, _module_version, _module_description, _module_author, _module_load, _module_unload, _module_game_changed. Commands, cvars and hooks registered through the helpers are undone automatically; override _module_unload for timers, files and sockets.

DotBanStoredot-server

_store_name, _load, _put, _remove, _refresh, _writable.

DotQueryProviderdot-server-query

_provider_name, _contribute(snapshot) — how a game publishes its own state into a server query. The bot count is the one that proves the point: nothing in a server framework can know it, because a bot never connects.

DotSecurityRuledot-server-security

An event name, a threshold, a window, a scope and a ladder of steps. Written as JSON or built in code, and guard.report_session(&"your.event", session) is enough to put a game’s own event through the whole engine.

DotBanFeeddot-server-security

url, auth, token_file, list_path, on_failure. Six auth modes and several list shapes, because a blocklist you cannot point this at is one you will copy into a file by hand, and then it is stale.

DotUserStore / DotAvatarStore / DotLoadoutStoredot-user, dot-user-avatar, dot-loadout

The same shape in all three: _fetch, _store, _remove, _open, _close, _writable, _store_name. A successful null means “this player has none”, which is not an error.

DotPunishmentStoredot-moderation

store_name, is_writable, load_all, put, update, remove. Paired with DotSqlDriver (dialect, open, execute, query, batch) when the backend is a database.

DotTimerStore / DotLeaderboardStoredot-timer, dot-leaderboard

put, top / page, best_for / entry_for, rank_of, count_on, remove. The manager sorts; the store does not have to.

DotMatchRulesdot-match

_points_for_kill, _round_outcome, _round_winner, _respawn_delay. DotRulesElimination is a worked example of what one is for.

DotTracedot-combat

_world_ray and nothing else. The hitbox walk, the wall-wins tie-break and the restore are the base class’s.

DotFpsBody / Dot2DBodydot-player-controller, dot-2d

sweep / move, overlaps, describe. The collision queries the motor needs, with a flat analytic implementation for determinism and a physics one for real geometry.

DotFpsMoveModedot-player-controller

_name, _enter, _exit, _simulate, _uses_crouch. A ladder, water, a grapple — using the motor’s own collision and acceleration.

DotVoiceCodecdot-voice

id, encode, decode, bytes_for, is_stateful, reset, duplicate_codec. Then DotVoiceCodec.register(...) and nothing else changes. This is the seam an Opus GDExtension drops into.

DotVoiceSource / DotVoiceSinkdot-voice

start, stop, has_frame / can_accept, read_frame / write_frame, is_running. Putting the devices behind an interface is the only reason the whole path has a headless test suite.

DotVoteSourcedot-vote

source_name, choices, current_id, supports_apply, apply. A source that cannot change anything is legitimate — the director emits change_due and the host acts on it.

DotPropTooldot-props

effective_reach, target, may_act_on. DotPhysGun and DotGravGun are the shipped subclasses.

DotScreen / DotHudWidgetdot-ui

_screen_id, _on_push, _on_pop, _on_cover, _on_reveal, _can_pop; and _on_value for a widget. Use _can_pop sparingly — a screen that refuses to close is a screen a player can be trapped in.

Callable hooks

The addon knows how to do the work; it does not know your world. These are the questions it refuses to guess at, grouped by what they answer.

Where the bytes go. DotNetManager.send_fn, DotVoiceManager.send_fn, DotVoiceRouter.send_fn, DotMapSyncHost.send_fn, DotMapSyncClient.send_fn. None of these addons owns a socket, which is why dot-net works over a loopback, a real transport, or your own.

Where a thing is. DotMatch.position_fn, DotVoiceRouter.position_fn, DotModTools.position_fn / teleport_fn. DotModTools takes Variant positions on purpose, so 2D is a first-class user rather than something to work around.

Who counts as what. DotDamageResolver.team_of, DotVoiceRouter.team_fn / listener_filter, DotVoteDirector.player_count_fn / is_admin_fn / is_spectator_fn / voters_fn / weight_fn, DotRulesElimination.alive_fn, DotModerationManager.key_for_peer, DotModTools.immunity_fn.

What a player owns or may be called. DotLoadoutManager.entitlement_source, DotPlatformHub.entitlement_source, DotUserManager.name_filter, DotItemCatalogue.resolver, DotAvatarCatalogue.resolver.

Where a shot rewinds to. DotCombatManager.rewind_fn / restore_fn. Two lines turn lag compensation on; unset, shots resolve against the present, which is right for a listen server and wrong for anyone with latency.

Everything else. DotSpawnSelector.danger_fn / filter_fn, DotDamageResolver.adjust, DotFpsMotor.surface_resolver, DotPickupField.wants_fn / tags_fn, DotHudWidget.source, DotStatBar.max_source, DotConVar.validator, DotConCommand.completer, DotBackboneClient.roster_provider / stats_provider, DotVoteDirector.announce_fn, DotVoteListSource.apply_fn, DotVoiceManager.sink_factory, DotNetVar.read_fn / write_fn / change_handler, DotNetSpawner.register_factory.

Resources you author

No code, no subclass — a .tres or a JSON file.

Resource What it decides
DotFpsTunables Every movement number. Layered: defaults < JSON < DOT_FPS_* < --fps-*
DotFpsSurface / DotFpsSurfaceSet Ice, mud, a conveyor. Multipliers, never absolute values, so retuning the base feel carries
DotFpsModifier A temporary change: speed pad, slow field, stun, launcher
DotFpsStyle A named variation — sideways, backwards, low gravity, prebhop
Dot2DTunables / Dot2DMassRules Top-down, thrust or blob; and how mass becomes size, speed and the right to eat somebody
DotWeapon / DotDamageType / DotHitGroup What a weapon is, how it hurts, and what a headshot is worth
DotDamageRules Friendly fire, self damage, falloff, clamping — in one order, once
DotItem / DotLoadoutSlot / DotLoadoutSchema A game mode’s equipment rules
DotAvatarSchema / DotAvatarSlot / DotAvatarPart What parts exist and what values are legal
DotMatchRules What winning means and what a kill is worth
DotSpawnPoint / DotTeam Where players appear and which side they are on
DotTimerZone / DotTimerZoneSet / DotTimerStyle What the timer reacts to, and what a ranked style is
DotMapDef in a catalogue JSON A map: an id, a version, a scene, optionally a content pack
DotPropDef / DotPropCatalogue / DotPropLimits What can be spawned, and how much of it
DotVoteRules Fifty-five settings, from the counting method to the tie-break
DotLeaderboardDef / DotStatsSchema What a board orders, and how a new reading meets an old one
DotUiTheme A whole Theme from a palette and a scale. No assets

Registry seams

Publish an object under one of these names and something else finds it, with neither side importing the other.

Name Published by Consulted by
dot_ban_source DotModerationManager, and dot-server-security’s feeds dot-server’s admission check — both are asked, and both must say yes
dot_query_host, dot_query_stats dot-server-query dot-server’s attach_query_host hook
dot_security, dot_anticheat, dot_security_bans dot-server-security its own console commands, and your own code
dot_random_source DotRandomManager, in dot-core anything wanting a stream it can reproduce
dot_mute_source DotModerationManager DotVoiceRouter
dot_cloud_client DotCloudClient dot-map’s loader, dot-server’s game change, dot-user-avatar’s catalogue
dot_user_manager DotUserManager dot-server, dot-platform
dot_avatar_manager DotAvatarManager dot-platform
dot_auth_server DotAuthServer dot-server, dot-platform
dot_platform DotPlatformHub DotPlatformModule
dot_server, dot_console, dot_event_bus, dot_game_manager, dot_module_host, dot_admin_manager, dot_ban_manager, dot_chat_manager, dot_audit_log, dot_rcon_server, dot_query_server, dot_query_source, dot_a2s_server, dot_vote_manager dot-server modules, and your own code
dot_client_link DotClientLink a game’s client code
dot_net_manager DotNetManager bridges
dot_match, dot_combat, dot_loadout, dot_fps_controller, dot_screen_stack, dot_2d_arena, dot_2d_controller, dot_voice_manager, dot_voice_router, dot_moderation, dot_mod_tools, dot_vote_director their own managers anything that needs them

Managers that can legitimately exist more than once in a tree take a service_scope, so two of them register under distinct names.

Server events you can hook or veto

DotEventBus.hook_pre(name, callable) runs before the event and may cancel it; hook_post runs after. Hooks run in registration order, and a hook that cancels stops the remaining pre-hooks — a cancelled event should not have half its handlers run.

Event Cancellable
server_start, server_shutdown no
client_connect, client_disconnect no
client_spawn no
client_kicked no
player_chat yes
player_command yes
game_changing yes
game_changed no
vote_started, vote_ended no
admin_action no

declare(name, description) registers your own, which is what makes it show up in the event_list console command — how a module author discovers what to hook without reading the source.