extends Object class_name SakuraPalette ## The palette, ported from the Sakura Crossing reference (MIT). ## ## Kept as hex strings rather than float triples so every value can be checked ## against the source line by line. `Color(hex)` parses sRGB, which is what the ## reference authors in and what a `source_color` shader uniform expects. ## ## ── The discipline, which matters more than any individual value ───────────── ## ## The palette is deliberately NARROW, and it is narrow in a specific way: ## ## * The masses are pale. Walls, paving, plaster, concrete and sky are all ## high-value and low-saturation. A cel image is read from its dark end, so ## the large areas have to stay out of the way or there is nothing left for ## the ink line and the shadow bands to be read against. ## * The greens lean TEAL, never yellow. A yellow-green mass at this scale ## goes sour and fights the pink. ## * There are exactly four saturated accents — red, yellow, blue, teal — and ## they are reserved for FOCAL objects: the crossing gear, the vending ## machines, a shop awning, the torii. If a saturated colour is spread over ## a large area it becomes the loudest thing in the frame and the eye stops ## going where the level designer wants it to. ## * Shadow is a HUE, not a value. Nothing here has a "dark version"; the cel ## shader swings every shadow band toward a cool violet instead. That is why ## there are so few dark entries in this table — the darks are made by the ## light, not by the paint. ## ## Deviating from those four rules is what makes a cel scene look like a ## low-poly 3D scene with a filter on it. # ── Sky & atmosphere ───────────────────────────────────────────────────────── const SKY_TOP := Color("8fbdea") const SKY_MID := Color("d4e8fa") const SKY_HAZE := Color("fbe7e9") const CLOUD := Color("fdfaf8") const CLOUD_SHADE := Color("e6e6f2") const FOG := Color("e6ecf7") const HILL := Color("c6cfe6") const HILL_FAR := Color("d8dded") # ── Light ──────────────────────────────────────────────────────────────────── const SUN := Color("fff1d8") const FILL := Color("a9bdf5") const HEMI_SKY := Color("dcecff") const HEMI_GROUND := Color("b6a6c6") # ── Ink ────────────────────────────────────────────────────────────────────── const INK := Color("39324f") const INK_SOFT := Color("4a4468") # ── Ground ─────────────────────────────────────────────────────────────────── const ROAD := Color("8e8a9c") const ROAD_WORN := Color("9a95a6") const ROAD_DARK := Color("7b7689") const LINE_WHITE := Color("f4f2f6") const LINE_YELLOW := Color("f0c341") const TACTILE := Color("f2c53d") const SIDEWALK := Color("dcd8e2") const SIDEWALK_ALT := Color("e7e2e6") const CURB := Color("c7c2d0") const CONCRETE := Color("d9d5dd") const CONCRETE_MID := Color("c2bdc8") const CONCRETE_DARK := Color("a7a2b0") const GUTTER := Color("bdb8c4") const DRAIN := Color("6d687a") const DIRT := Color("c9bfae") const GRAVEL := Color("a9a3ab") const BALLAST := Color("7d7686") # ── Buildings ──────────────────────────────────────────────────────────────── const WALL_WHITE := Color("faf6ef") const WALL_CREAM := Color("f2e7d3") const WALL_BLUE := Color("d6e3ee") const WALL_BEIGE := Color("e7dbc4") const WALL_GRAY := Color("dedee6") const WALL_PINK := Color("f0dcda") const WALL_TEA := Color("dccdb6") const WALL_SAGE := Color("dde2d6") const ROOF_SLATE := Color("59617a") const ROOF_BLUE := Color("4d5c78") const ROOF_BROWN := Color("6b585c") const ROOF_TEAL := Color("4f6b70") const TRIM := Color("8b8496") const GLASS := Color("9dc0d4") const GLASS_DARK := Color("53627a") const SHUTTER := Color("6e6a7a") const SHUTTER_LIGHT := Color("847f92") ## The wall tones, as a list, for generators that want variety by index. const WALLS: Array[Color] = [ WALL_WHITE, WALL_CREAM, WALL_BLUE, WALL_BEIGE, WALL_GRAY, WALL_PINK, WALL_TEA, WALL_SAGE, ] const ROOFS: Array[Color] = [ROOF_SLATE, ROOF_BLUE, ROOF_BROWN, ROOF_TEAL] # ── Accents ────────────────────────────────────────────────────────────────── # The four saturated colours, plus their deep variants. Focal objects only. const RED := Color("e0453f") const RED_DEEP := Color("b5322f") const RED_SOFT := Color("ef6a60") const YELLOW := Color("f4c033") const YELLOW_DEEP := Color("d39c1f") const BLACK := Color("322e3b") const BLACK_SOFT := Color("453f4f") const TEAL := Color("2f9c9a") const TEAL_DEEP := Color("22736f") const BLUE := Color("3d6ec4") const BLUE_DEEP := Color("2a4f97") const ORANGE := Color("ef8a3c") const PURPLE := Color("8f6fb5") # ── Vegetation ─────────────────────────────────────────────────────────────── const LEAF := Color("5aa578") const LEAF_DEEP := Color("3f7f60") const LEAF_PALE := Color("84bd97") const GRASS := Color("86ab84") const TRUNK := Color("9a8082") const TRUNK_DARK := Color("765f62") const MOSS := Color("7d9c74") const BAMBOO := Color("94b06b") const CEDAR := Color("3f6b52") # ── Cherry blossom ─────────────────────────────────────────────────────────── const BLOSSOM := Color("fbc6d8") const BLOSSOM_LIGHT := Color("fff0f4") const BLOSSOM_WARM := Color("fedde2") const BLOSSOM_DEEP := Color("f0a3c0") const PETAL := Color("fcd9e4") const PETAL_DEEP := Color("f6bccf") # ── Railway ────────────────────────────────────────────────────────────────── const RAIL_METAL := Color("6b6472") const RAIL_HEAD := Color("c2bcc4") const SLEEPER := Color("6d6576") const SLEEPER_LIGHT := Color("847b8c") const GATE_YELLOW := Color("f4c033") const GATE_BLACK := Color("322e3b") const SIGNAL_RED := Color("f2453c") const SIGNAL_OFF := Color("6a3b44") const CABINET := Color("d8d5da") const CABINET_TOP := Color("b6b2bc") # ── Train ──────────────────────────────────────────────────────────────────── const TRAIN_BODY := Color("f7f2e6") const TRAIN_BODY_SHADE := Color("e6dfd0") const TRAIN_STRIPE := Color("2f7fd0") const TRAIN_STRIPE2 := Color("3fae9a") const TRAIN_WINDOW := Color("3a4258") const TRAIN_SKIRT := Color("9aa0ad") const TRAIN_ROOF := Color("bdb8bd") const TRAIN_DOOR := Color("eae4d8") # ── Metal & props ──────────────────────────────────────────────────────────── const METAL := Color("b8bcc6") const METAL_DARK := Color("878b96") const METAL_WARM := Color("c9c0b4") const MIRROR_BACK := Color("e4a83c") const MIRROR_FACE := Color("c8d8e4") const VEND_WHITE := Color("f8f5f0") const VEND_RED := Color("db4038") const VEND_TEAL := Color("2e9a98") const CRATE := Color("3f7fbf") const CRATE_ALT := Color("e25a4a") const BASKET := Color("db5a4a") const BIN := Color("5d8fb8") ## Bright can/bottle colours for vending machine shelves. const DRINKS: Array[Color] = [ Color("e0453f"), Color("f4c033"), Color("3d6ec4"), Color("2f9c9a"), Color("ef8a3c"), Color("8f6fb5"), Color("5aa578"), Color("f4f2f6"), Color("e86f9c"), Color("44b4d8"), Color("c94f7a"), Color("9dbb3c"), ] # ── Shopping street ────────────────────────────────────────────────────────── const AWNING_GREEN := Color("4f8f6a") const AWNING_ORANGE := Color("e08a3c") const AWNING_BLUE := Color("4a7fae") const AWNING_CREAM := Color("efe0c2") const LANTERN := Color("f6e2c0") const LANTERN_LIT := Color("ffd9a0") const NOREN := Color("2f4a72") const NOREN_RED := Color("b5322f") const NOREN_CREAM := Color("f2e8d6") const AWNINGS: Array[Color] = [ AWNING_GREEN, AWNING_ORANGE, AWNING_BLUE, AWNING_CREAM, NOREN, NOREN_RED, ] # ── Shrine ─────────────────────────────────────────────────────────────────── const TORII := Color("d8412f") const TORII_DEEP := Color("a72f23") const SHRINE_WOOD := Color("a9744f") const SHRINE_WOOD_DARK := Color("8a604a") const SHRINE_ROOF := Color("69707e") const SHRINE_STONE := Color("cfcad2") const ROPE := Color("f0e5ca") const EMA := Color("e9d9b6") # ── Stone & water ──────────────────────────────────────────────────────────── const STONE := Color("c6c0cb") const STONE_DARK := Color("a39daf") const STONE_WARM := Color("cfc6bc") const WATER := Color("93b8ce") const WATER_DEEP := Color("6d90ad") const WATER_SKY := Color("cadff0") const WATER_PETAL := Color("f3cada") ## ── Shadow tints ───────────────────────────────────────────────────────────── ## ## The cool violet each material's shadow bands swing toward. The reference's ## default is 0x6c5f8c and most things take it; the departures are all the same ## kind of decision, which is that a shadow keeps a memory of what the surface is ## MADE of: ## ## TINT_WARM timber, blossom, clay, lantern paper. Pushing these the full ## way to violet turns cedar grey and turns a cherry canopy into a ## storm cloud, which is the one thing it may never do. ## TINT_COOL metal, glass, water, rail. These genuinely are cooler in shade ## than anything else in the frame, and letting them go further ## than the default is most of what makes metal read as metal ## without a specular highlight. const TINT := Color("6c5f8c") const TINT_WARM := Color("8a7286") const TINT_COOL := Color("5a5a8c") const TINT_FOLIAGE := Color("6a7a8c")