Cryptid Hotel — Internal Dev Doc

Coding
Conventions

Dev team only · Read before writing a single line
Version 1.0
Engine Godot 4.6 · GDScript
Applies to Dev team
Updated March 2026
Core Rules — No Exceptions

Before writing anything

🔡
Always type hint Every variable and every function return must have a type. No bare var x.
🐍
snake_case everywhere Variables, functions, signals, file names. Only classes and enum names use PascalCase.
📐
Script structure order Always follow the defined order. class_name → signals → enums → constants → exported variables → public variables → private variables → functions.
💬
Comment why, not what The code says what. Comments explain design decisions and non-obvious intent only.
01

Naming Conventions

CaseExampleUsed for
snake_case noise_level, check_satisfaction variables functions signals files
PascalCase FresnoNightcrawler, AuraType class_name enum names
SCREAMING_SNAKE MAX_CLIENTS, BASE_DAMAGE constants enum values
_snake_case _cached_value, _calculate_aura private vars private funcs
is_ / has_ / can_ is_satisfied, has_aura, can_place booleans
past tense day_ended, client_placed, room_removed all signals
02

Variables

Variables · always type hint
# Constant const MAX_ITEMS_PER_ROOM: int = 4 # Exported variable — inspector-visible @export var client_race: ClientRace = ClientRace.YETI # Public variable — typed, initialized var is_noisy: bool = false var room_count: int = 0 var is_satisfied: bool = false # Private variable — underscore prefix var _cached_aura: int = 0 var _adjacent_rooms: Array[RoomBase] = [] # ❌ Never do this var n = 0 # no name, no type var satisfied = false # boolean needs is_ prefix + type hint
03

Functions

Functions · typed params + return
# Public function — typed params, typed return func check_satisfaction(client: ClientBase) -> bool: return client.has_all_requirements_met() # Void function — explicit void return type func place_client(client: ClientBase, room: RoomBase) -> void: room.add_client(client) # Private function — underscore prefix func _calculate_aura_spread(origin: Vector2i) -> Array[RoomBase]: pass # ❌ Never do this func doStuff(): # camelCase, no types pass func go() -> void: # meaningless name pass
04

Signals

past tense · typed params
Signals
# Past tense — something already happened signal client_placed(client: ClientBase, room: RoomBase) signal day_ended(day_number: int) signal client_satisfied(client: ClientBase) signal room_placed(room: RoomBase, grid_pos: Vector2i) signal aura_spread(aura_type: AuraType, origin: Vector2i) signal damage_taken(amount: int) # ❌ Never do this signal dayEnd # camelCase, no params signal on_client_happy # on_ is for listeners, not declarations
05

Enums

PascalCase name · SCREAMING values
Enums
enum AuraType { DARKNESS, FEAR, NOISE, COLD, HUNGER, NEARBY_CLIENTS } enum ClientRace { FRESNO_NIGHTCRAWLER, WENDIGO, GIANT_CICADA, YETI, HOPKINSVILLE_GOBLIN, MODDEY_DOO } enum ZoneID { ZONE_1, ZONE_2, ZONE_3, ZONE_4 } # ❌ Never do this enum auratype { noise, cold } # lowercase name, lowercase values
06

Comments

explain why · not what
Comment style
# ✅ Aura spreads to 4 adjacent rooms only — diagonals ignored by design func _spread_aura(origin: Vector2i) -> void: pass # ✅ Damage resolves at end of day only, not in real time # Avoids mid-day state changes breaking the satisfaction check func _resolve_day_end() -> void: pass # ❌ Increment room count by 1 ← restates the code, useless room_count += 1 # ✅ Section separator for long scripts # ============================================================ # AURA SYSTEM # ============================================================ # ✅ TODO's and FIXME's # TODO : replace placeholder with real satisfaction formula # FIXME: aura not propagating correctly on room removal
07

Script Structure Order

always in this exact order
01 class_name + extends class_name FresnoNightcrawler extends ClientBase
02 signals signal client_satisfied(client: ClientBase)
03 enums enum AuraType { NOISE, COLD ... }
04 constants const MAX_CLIENTS: int = 10
05 @export variables @export var base_fear: float = 0.0
06 public variables var room_count: int = 0
07 private variables var _cached_value: int = 0
08 _ready() · _init() built-in Godot callbacks first
09 _process() · _physics_process() frame callbacks
10 public functions func place_room() -> void:
11 private functions func _calculate_aura() -> int:
08

Common Mistakes

var n = 3 var attack_damage: int = 3
func doStuff(): func check_satisfaction() -> bool:
var satisfied = false var is_satisfied: bool = false
class_name nightcrawler class_name FresnoNightcrawler
signal dayEnd signal day_ended(day_number: int)
enum auratype { noise, cold } enum AuraType { NOISE, COLD }
# increment room count by 1 # room added after day end only, not mid-day