From f9cad7842d21d89c97d9bf1dd45ade4d7f0c8dbd Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 29 Sep 2026 13:23:09 +0000 Subject: [PATCH] Improve The Sunken Crypt's graphics: warm light, props and motion The room painter now lights with warm firelight and cool daylight: where fire dominates, stone, floor and wood swap to warm twins of their ramps with a dithered edge. Seams and the floor under props are shaded, the ceiling has ribs carried down the walls as pilasters, side passages show depth, and the rooms gain banners, weapon racks, a crate, an altar with carvings, rubble lit by daylight, open treasure chests and glowing skeleton eyes. Dithering is gentler so flat areas read cleaner. In the game, demo/room_fx.gd flickers pixels in the painter's flame ramp, raises embers from the brightest flame pixels, and dissolves between rooms in Bayer order. Framed panels get brass corner pieces, and the menu title an outline over the brighter backdrop. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01YEf4Qot4HstXVdXff3c9if --- godot-jev/README.md | 25 +- godot-jev/demo/adventure.gd | 33 +- godot-jev/demo/art/antechamber.png | Bin 5720 -> 6928 bytes godot-jev/demo/art/armory.png | Bin 6047 -> 8418 bytes godot-jev/demo/art/hall.png | Bin 5850 -> 7120 bytes godot-jev/demo/art/hall_cleared.png | Bin 5221 -> 6446 bytes godot-jev/demo/art/ossuary.png | Bin 6057 -> 6283 bytes godot-jev/demo/art/stairs.png | Bin 6939 -> 8114 bytes godot-jev/demo/art/vault.png | Bin 7165 -> 7843 bytes godot-jev/demo/room_fx.gd | 125 ++++++++ godot-jev/demo/room_fx.gd.uid | 1 + godot-jev/demo/start_menu.gd | 13 +- godot-jev/demo/style.gd | 46 ++- godot-jev/docs/screenshot.png | Bin 24699 -> 33800 bytes godot-jev/tests/run_tests.gd | 1 + godot-jev/tests/test_room_fx.gd | 59 ++++ godot-jev/tests/test_room_fx.gd.uid | 1 + godot-jev/tools/paint_rooms.gd | 470 +++++++++++++++++++++------- 18 files changed, 646 insertions(+), 128 deletions(-) create mode 100644 godot-jev/demo/room_fx.gd create mode 100644 godot-jev/demo/room_fx.gd.uid create mode 100644 godot-jev/tests/test_room_fx.gd create mode 100644 godot-jev/tests/test_room_fx.gd.uid diff --git a/godot-jev/README.md b/godot-jev/README.md index f5ca733..0c7939e 100644 --- a/godot-jev/README.md +++ b/godot-jev/README.md @@ -60,7 +60,7 @@ the menu. | Area | What it shows | | --- | --- | -| Room art (top left) | A 160×90 pixel scene for the current room, scaled 4×. It fades between rooms, drops to near-black in a dark room without light, and switches to a room's variant art once the variant's flag is set (the hall after the skeleton falls). The room's name sits on a plaque in the corner. | +| Room art (top left) | A 160×90 pixel scene for the current room, scaled 4×. Fires flicker and shed embers, and rooms change through a dithered dissolve. It drops to near-black in a dark room without light, and switches to a room's variant art once the variant's flag is set (the hall after the skeleton falls). The room's name sits on a plaque in the corner. | | Status panel (bottom left) | Exits and what you're carrying, plus **Jev heard**: the latest outcome (act, clarify, unknown, or error when the API is unreachable), the action it chose, a confidence meter with ticks at the clarify (0.40) and act (0.75) thresholds, and the turn's latency. It's there to make the experiment visible while playing. | | Transcript (right) | Room names as headings, your commands echoed in muted text, item lines highlighted, and new text revealed a few characters at a time. Clarify options are links: click one, or type 1 or 2. | | Turn scores | Each command Jev answered ends with its outcome and confidence (`act 0.94`, `clarify 0.52`, `offline`). Click one to open that turn's card: what you typed, the outcome and move, confidence against the thresholds, latency, how many options were offered, API calls, the model, and the top three candidates with their probabilities. Esc or a click elsewhere closes it. | @@ -106,12 +106,22 @@ godot --headless --path . --script res://tools/paint_rooms.gd ``` `tools/paint_rooms.gd` draws each room in one-point perspective (brick walls, a flagstone floor -and a vaulted ceiling), cuts doorways for the room's exits in `world.json` (north is an arch in the -back wall; east and west are openings in the side walls; south is behind the viewer), and adds -props from small ASCII sprites: the skeleton, braziers, sconces, skull niches, chests and the crown. +and a vaulted ceiling with ribs carried down the walls as pilasters), cuts doorways for the room's +exits in `world.json` (north is an arch in the back wall; east and west are passages in the side +walls; south is behind the viewer), and adds props from small ASCII sprites and painters: the +skeleton, braziers, sconces, banners, weapon racks, skull niches, the altar, chests and the crown. Lighting is computed per pixel from each room's lights and then snapped to fixed colour ramps with 4×4 Bayer dithering, so the output stays a limited-palette pixel image rather than a smooth -gradient. +gradient. Lights are warm (fire) or cool (daylight, bounce): where firelight dominates, stone, +floor and wood swap to warm twins of their ramps, with a dithered edge, so torchlight pools amber +against cold violet shadow. Seams between walls, floor and ceiling, and the floor under props, +are shaded darker. + +In the game, `demo/room_fx.gd` animates the still image with a shader. Pixels in exactly the +flame ramp's colours step up and down that ramp, the scene brightens and dims slightly with the +firelight, and embers rise from the brightest flame pixels. Room changes dissolve pixel by pixel +in Bayer order. Hand-made art without those exact colours is shown as it is, with no flicker or +embers. To use real art, replace any file with a 160×90 PNG of the same name: the room id, or the variant's `art` name. `test_every_room_and_variant_has_art` fails if one is missing. Dark rooms @@ -128,11 +138,12 @@ don't need separate art; the scene dims the room's image at runtime. | `demo/start_menu.gd` | The start menu (the main scene) and its help page | | `demo/help.gd` | BBCode for the help page, and the menu's Jev status line | | `demo/adventure.gd` | The playable scene: art, status panel, transcript and input | -| `demo/style.gd` | Palette, fonts, framed panels and theme shared by the menu and the game | +| `demo/style.gd` | Palette, fonts, brass-cornered panels and theme shared by the menu and the game | +| `demo/room_fx.gd` | Flame flicker, embers and the dissolve between rooms, for the menu and the game | | `demo/transcript.gd` | BBCode for the transcript; escapes all authored and typed text | | `demo/art/`, `demo/fonts/` | Room images and the two pixel fonts | | `tools/paint_rooms.gd` | Regenerates the placeholder room art | -| `tests/` | A headless runner and 34 tests; a script error inside a test counts as a failure | +| `tests/` | A headless runner and 40 tests; a script error inside a test counts as a failure | Using the add-on in any game: diff --git a/godot-jev/demo/adventure.gd b/godot-jev/demo/adventure.gd index 5201cb3..2a6f2f3 100644 --- a/godot-jev/demo/adventure.gd +++ b/godot-jev/demo/adventure.gd @@ -7,6 +7,7 @@ const World := preload("res://demo/world.gd") const Parser := preload("res://demo/parser.gd") const Transcript := preload("res://demo/transcript.gd") const Style := preload("res://demo/style.gd") +const RoomFx := preload("res://demo/room_fx.gd") const TITLE_FONT := Style.TITLE_FONT const NOT_UNDERSTOOD := [ @@ -33,6 +34,8 @@ var reveal: Tween var shown_art := "" var art: TextureRect +var art_holder: Control +var embers: CPUParticles2D var plaque: Label var exits_label: Label var pack_label: Label @@ -194,12 +197,31 @@ func _refresh() -> void: return var first := shown_art.is_empty() shown_art = art_name - var target := DARKNESS if world.is_dark() else Color.WHITE var fade := create_tween() if not first: - fade.tween_property(art, "modulate", Color.BLACK, 0.15) - fade.tween_callback(func(): art.texture = load(World.art_path(world.art()))) - fade.tween_property(art, "modulate", target, 0.35) + fade.tween_method(_set_reveal, 1.0, 0.0, 0.3) + fade.tween_callback(_show_art.bind(world.art(), world.is_dark())) + fade.tween_method(_set_reveal, 0.0, 1.0, 0.45) + + +## Swaps the room image while it's fully dissolved. A dark room keeps its +## art but dimmed, and nothing burns in it. +func _show_art(art_name: String, dark: bool) -> void: + var texture: Texture2D = load(World.art_path(art_name)) + art.texture = texture + art.modulate = DARKNESS if dark else Color.WHITE + if embers: + embers.queue_free() + var pixel := minf(art_holder.size.x / texture.get_width(), art_holder.size.y / texture.get_height()) + var sources := PackedVector2Array() if dark else RoomFx.ember_sources(texture.get_image()) + embers = RoomFx.embers(sources, pixel) + embers.position = (art_holder.size - texture.get_size() * pixel) / 2.0 + art_holder.add_child(embers) + art_holder.move_child(embers, art.get_index() + 1) + + +func _set_reveal(amount: float) -> void: + (art.material as ShaderMaterial).set_shader_parameter("reveal", amount) func _show_decision(result: Dictionary, elapsed_ms: int, texts: Dictionary) -> void: @@ -286,7 +308,10 @@ func _details_popup() -> PopupPanel: func _art_view() -> Control: var holder := Control.new() holder.custom_minimum_size = Vector2(640, 360) + holder.clip_contents = true + art_holder = holder art = TextureRect.new() + art.material = RoomFx.material() art.set_anchors_preset(Control.PRESET_FULL_RECT) art.expand_mode = TextureRect.EXPAND_IGNORE_SIZE art.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED diff --git a/godot-jev/demo/art/antechamber.png b/godot-jev/demo/art/antechamber.png index 65e049a16f689901b07dea1438faa33b006e10e5..006251fd2520cc0d2d06f79fc2ca5dec3b32342c 100644 GIT binary patch literal 6928 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 KMNUMnLSTYmvy<)s diff --git a/godot-jev/demo/art/armory.png b/godot-jev/demo/art/armory.png index 8371c8364e2860415844c3d7e34533c4072708b6..b658b79605d125f05e614e03adcefa14ad69018a 100644 GIT binary patch literal 8418 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%0Ae7s&579akW2|K6pEm#ThR^OR`04@WRbG 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 diff --git a/godot-jev/demo/art/hall_cleared.png b/godot-jev/demo/art/hall_cleared.png index 3927c839da20092fff2667ad0027b4b7a3b11a5b..4901407e9f549e7d5b6c9316e15414da48b8edd9 100644 GIT binary patch literal 6446 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 B#@zq_ literal 6057 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 M07*qoM6N<$f?8j31ONa4 literal 6939 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 diff --git a/godot-jev/demo/art/vault.png b/godot-jev/demo/art/vault.png index 8138eea9eea99c194de3c965329a7026da2e6fe2..db8cb0511e89990a4bd9dcf9881b9e4245cd4c74 100644 GIT binary patch literal 7843 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 B-!uRK literal 7165 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 diff --git a/godot-jev/demo/room_fx.gd b/godot-jev/demo/room_fx.gd new file mode 100644 index 0000000..cac5abe --- /dev/null +++ b/godot-jev/demo/room_fx.gd @@ -0,0 +1,125 @@ +extends RefCounted +## Motion for the still room art: fires flicker, embers rise from them, and +## rooms change through a dithered dissolve. The painter's flame ramp is the +## key. Only pixels in exactly those colours flicker or shed embers, so +## hand-made art in other colours is left alone. + +## The flame ramp, dark to light. tools/paint_rooms.gd paints fire with it. +const FLAME := ["3a0e04", "8a2a06", "d65a0e", "f59a1c", "ffd24a", "fff6c0"] +## Art pixels in the brightest steps of FLAME become ember sources. +const EMBER_STEPS := 2 +const MAX_EMBERS := 24 + +const SHADER := """ +shader_type canvas_item; + +// The flame ramp, dark to light; flame pixels step along it over time. +uniform vec4 flame[6]; +uniform vec2 art_size = vec2(160.0, 90.0); +// 1 shows the whole image; below 1, pixels drop out in Bayer order. +uniform float reveal : hint_range(0.0, 1.0) = 1.0; +// How much the whole scene brightens and dims with the firelight. +uniform float breathing = 0.035; + +// The node's modulate, kept apart because COLOR in fragment() already +// includes the texture. +varying vec4 tint; + +float hash(vec2 p) { + return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453); +} + +float bayer4(vec2 p) { + int x = int(mod(p.x, 4.0)); + int y = int(mod(p.y, 4.0)); + int m[16] = int[](0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5); + return (float(m[y * 4 + x]) + 0.5) / 16.0; +} + +void vertex() { + tint = COLOR; +} + +void fragment() { + vec4 c = texture(TEXTURE, UV); + vec2 px = floor(UV * art_size); + for (int i = 0; i < 6; i++) { + if (distance(c.rgb, flame[i].rgb) < 0.02) { + vec2 cell = floor(px / vec2(2.0, 3.0)); + float tick = floor(TIME * 9.0 + hash(cell) * 4.0); + float n = hash(cell + tick); + int j = clamp(i + (n > 0.7 ? 1 : (n < 0.3 ? -1 : 0)), 0, 5); + c.rgb = flame[j].rgb; + break; + } + } + float wave = sin(TIME * 7.1) * 0.5 + sin(TIME * 12.7 + 1.3) * 0.3 + sin(TIME * 2.3) * 0.2; + c.rgb *= 1.0 + breathing * wave; + if (bayer4(px) >= reveal) { + c.rgb = vec3(0.0); + } + COLOR = c * tint; +} +""" + + +static func material(art_size := Vector2(160, 90)) -> ShaderMaterial: + var shader := Shader.new() + shader.code = SHADER + var mat := ShaderMaterial.new() + mat.shader = shader + mat.set_shader_parameter("flame", FLAME.map(func(hex): return Color(hex))) + mat.set_shader_parameter("art_size", art_size) + return mat + + +## Art-pixel positions of the brightest flame pixels, at most MAX_EMBERS of +## them, spread evenly through the image. +static func ember_sources(image: Image) -> PackedVector2Array: + var hot: Array = FLAME.slice(FLAME.size() - EMBER_STEPS).map(func(hex): return Color(hex)) + var found := PackedVector2Array() + for y in image.get_height(): + for x in image.get_width(): + var c := image.get_pixel(x, y) + for h: Color in hot: + if absf(c.r - h.r) + absf(c.g - h.g) + absf(c.b - h.b) < 0.03: + found.append(Vector2(x, y)) + break + if found.size() <= MAX_EMBERS: + return found + var spread := PackedVector2Array() + for i in MAX_EMBERS: + spread.append(found[i * found.size() / MAX_EMBERS]) + return spread + + +## Embers drifting up from `sources` (art pixels), drawn as whole art pixels +## at `pixel` screen pixels each. +static func embers(sources: PackedVector2Array, pixel: float) -> CPUParticles2D: + var p := CPUParticles2D.new() + var dot := Image.create(1, 1, false, Image.FORMAT_RGBA8) + dot.fill(Color.WHITE) + p.texture = ImageTexture.create_from_image(dot) + p.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST + p.emission_shape = CPUParticles2D.EMISSION_SHAPE_POINTS + var points := PackedVector2Array() + for s in sources: + points.append((s + Vector2(0.5, 0.5)) * pixel) + p.emission_points = points + p.emitting = not points.is_empty() + p.amount = clampi(points.size() / 2, 3, 12) + p.lifetime = 1.6 + p.preprocess = 1.6 + p.direction = Vector2.UP + p.spread = 25.0 + p.gravity = Vector2(0, -6 * pixel) + p.initial_velocity_min = 2.0 * pixel + p.initial_velocity_max = 5.0 * pixel + p.scale_amount_min = pixel * 0.5 + p.scale_amount_max = pixel + var fade := Gradient.new() + fade.set_color(0, Color(FLAME[5])) + fade.set_color(1, Color(Color(FLAME[2]), 0.0)) + fade.add_point(0.4, Color(FLAME[4])) + p.color_ramp = fade + return p diff --git a/godot-jev/demo/room_fx.gd.uid b/godot-jev/demo/room_fx.gd.uid new file mode 100644 index 0000000..a1d0156 --- /dev/null +++ b/godot-jev/demo/room_fx.gd.uid @@ -0,0 +1 @@ +uid://c82fkff1dvrrt diff --git a/godot-jev/demo/start_menu.gd b/godot-jev/demo/start_menu.gd index 2195e8d..f209269 100644 --- a/godot-jev/demo/start_menu.gd +++ b/godot-jev/demo/start_menu.gd @@ -6,6 +6,7 @@ const Style := preload("res://demo/style.gd") const Help := preload("res://demo/help.gd") const Parser := preload("res://demo/parser.gd") const World := preload("res://demo/world.gd") +const RoomFx := preload("res://demo/room_fx.gd") const GAME := "res://demo/adventure.tscn" const BACKDROP := "stairs" const TAGLINE := "Type anything. Only what the author wrote can happen." @@ -32,8 +33,16 @@ func _ready() -> void: art.expand_mode = TextureRect.EXPAND_IGNORE_SIZE art.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_COVERED art.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST - art.modulate = Color(0.35, 0.32, 0.4) + art.modulate = Color(0.5, 0.45, 0.55) + art.material = RoomFx.material() add_child(art) + var screen := get_viewport_rect().size + var art_size := art.texture.get_size() + var pixel := maxf(screen.x / art_size.x, screen.y / art_size.y) # the art covers the screen + var embers := RoomFx.embers(RoomFx.ember_sources(art.texture.get_image()), pixel) + embers.position = (screen - art_size * pixel) / 2.0 + embers.modulate = Color(1, 1, 1, 0.6) + add_child(embers) title_view = _title_view() add_child(title_view) help_view = _help_view() @@ -77,6 +86,8 @@ func _title_view() -> Control: title.add_theme_color_override("font_shadow_color", Style.BG) title.add_theme_constant_override("shadow_offset_x", 4) title.add_theme_constant_override("shadow_offset_y", 4) + title.add_theme_color_override("font_outline_color", Style.BG) + title.add_theme_constant_override("outline_size", 12) column.add_child(title) var tagline := Label.new() tagline.text = TAGLINE diff --git a/godot-jev/demo/style.gd b/godot-jev/demo/style.gd index 2ec61b0..950ded5 100644 --- a/godot-jev/demo/style.gd +++ b/godot-jev/demo/style.gd @@ -12,6 +12,7 @@ const EDGE_DARK := Color("2a2130") const INK := Color("e8dcc0") const DIM := Color("8d82a3") const GOLD := Color("f0b85a") +const BRASS := Color("b08a4a") ## Pixel fonts stay sharp only without antialiasing, hinting or subpixel offsets. @@ -34,15 +35,20 @@ static func box(fill: Color, border: Color, width: int, padding: Vector4) -> Sty return style -## A double border: a dark outer line around a brass inner line. +## A double border: a dark outer line around a brass inner line, with brass +## corner pieces riveted over it. static func framed(content: Control) -> PanelContainer: var outer := PanelContainer.new() outer.add_theme_stylebox_override("panel", box(EDGE_DARK, BG, 2, Vector4.ONE * 2)) var inner := PanelContainer.new() - inner.add_theme_stylebox_override("panel", box(PANEL, EDGE, 2, Vector4.ONE * 12)) + var fill := box(PANEL, EDGE, 2, Vector4.ONE * 12) + fill.shadow_color = Color(0, 0, 0, 0.45) + fill.shadow_size = 6 + inner.add_theme_stylebox_override("panel", fill) inner.size_flags_vertical = Control.SIZE_EXPAND_FILL outer.add_child(inner) inner.add_child(content) + outer.add_child(Corners.new()) return outer @@ -79,3 +85,39 @@ static func theme() -> Theme: t.set_stylebox("focus", "Button", box(Color(0, 0, 0, 0), GOLD, 2, pad)) t.set_stylebox("pressed", "Button", box(GOLD, GOLD, 2, pad)) return t + + +## Brass L-shaped corner pieces with a rivet, drawn in whole 2px steps so +## they sit on the same grid as the pixel fonts. +class Corners: + extends Control + + const ARM := 14 + const THICK := 4 + + func _init() -> void: + mouse_filter = Control.MOUSE_FILTER_IGNORE + + func _draw() -> void: + for corner in [Vector2(0, 0), Vector2(1, 0), Vector2(0, 1), Vector2(1, 1)]: + var flip := Vector2(1 - 2 * corner.x, 1 - 2 * corner.y) + var at := Vector2(corner.x * size.x, corner.y * size.y) + _piece(at, flip) + + func _piece(at: Vector2, flip: Vector2) -> void: + for layer in [[BG, 2], [BRASS, 0]]: + var grow: float = layer[1] + var horizontal := Rect2(-grow, -grow, ARM + grow * 2, THICK + grow * 2) + var vertical := Rect2(-grow, -grow, THICK + grow * 2, ARM + grow * 2) + for r: Rect2 in [horizontal, vertical]: + draw_rect(_place(r, at, flip), layer[0]) + draw_rect(_place(Rect2(0, 0, ARM, 2), at, flip), GOLD) + draw_rect(_place(Rect2(0, 0, 2, ARM), at, flip), GOLD) + draw_rect(_place(Rect2(THICK + 2, THICK + 2, 4, 4), at, flip), BG) + draw_rect(_place(Rect2(THICK + 2, THICK + 2, 2, 2), at, flip), GOLD) + + ## Mirrors a rect drawn for the top-left corner into any corner. + func _place(r: Rect2, at: Vector2, flip: Vector2) -> Rect2: + var a := at + r.position * flip + var b := at + r.end * flip + return Rect2(Vector2(minf(a.x, b.x), minf(a.y, b.y)), (b - a).abs()) diff --git a/godot-jev/docs/screenshot.png b/godot-jev/docs/screenshot.png index e1b52bbba394548f6be3a945660285494758afea..8cd4b14056860ead0524ce471084ec03f9757dc4 100644 GIT binary patch literal 33800 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 diff --git a/godot-jev/tests/run_tests.gd b/godot-jev/tests/run_tests.gd index aac2546..4812760 100644 --- a/godot-jev/tests/run_tests.gd +++ b/godot-jev/tests/run_tests.gd @@ -13,6 +13,7 @@ const SUITES := [ "res://tests/test_parser.gd", "res://tests/test_transcript.gd", "res://tests/test_menu.gd", + "res://tests/test_room_fx.gd", ] var failures := 0 diff --git a/godot-jev/tests/test_room_fx.gd b/godot-jev/tests/test_room_fx.gd new file mode 100644 index 0000000..5cb65d5 --- /dev/null +++ b/godot-jev/tests/test_room_fx.gd @@ -0,0 +1,59 @@ +extends "res://tests/suite.gd" + +const RoomFx := preload("res://demo/room_fx.gd") +const Style := preload("res://demo/style.gd") + + +func _image_with(pixels: Dictionary) -> Image: + var image := Image.create(8, 6, false, Image.FORMAT_RGB8) + image.fill(Color("3a3347")) + for at: Vector2i in pixels: + image.set_pixelv(at, Color(pixels[at])) + return image + + +func test_embers_rise_only_from_the_brightest_flame_pixels() -> void: + var image := _image_with({ + Vector2i(2, 1): RoomFx.FLAME[5], Vector2i(5, 4): RoomFx.FLAME[4], + Vector2i(6, 4): RoomFx.FLAME[1], Vector2i(0, 0): "efc13a", # the crown's gold + }) + var sources := RoomFx.ember_sources(image) + eq(Array(sources), [Vector2(2, 1), Vector2(5, 4)], "ember sources") + + +func test_art_without_fire_has_no_embers() -> void: + var embers := RoomFx.embers(RoomFx.ember_sources(_image_with({})), 4.0) + check(not embers.emitting, "nothing emits") + embers.free() + + +func test_ember_sources_are_capped_and_spread_through_the_fire() -> void: + var image := Image.create(40, 2, false, Image.FORMAT_RGB8) + image.fill(Color(RoomFx.FLAME[5])) + var sources := RoomFx.ember_sources(image) + eq(sources.size(), RoomFx.MAX_EMBERS, "capped") + check(sources[0].y == 0 and sources[sources.size() - 1].y == 1, "spread across both rows") + + +func test_embers_are_placed_in_screen_pixels() -> void: + var embers := RoomFx.embers(PackedVector2Array([Vector2(10, 5)]), 4.0) + eq(Array(embers.emission_points), [Vector2(42, 22)], "centre of art pixel (10, 5) at 4x") + check(embers.emitting, "emits") + embers.free() + + +func test_the_room_material_carries_the_flame_ramp() -> void: + var mat := RoomFx.material() + var flame: Array = mat.get_shader_parameter("flame") + eq(flame.size(), RoomFx.FLAME.size(), "every step") + eq(flame[0], Color(RoomFx.FLAME[0]), "darkest first") + + +func test_framed_panels_get_brass_corners_over_their_content() -> void: + var content := Label.new() + var frame := Style.framed(content) + var corners := frame.get_child(frame.get_child_count() - 1) + check(corners is Style.Corners, "corners are drawn last, over the panel") + eq((corners as Control).mouse_filter, Control.MOUSE_FILTER_IGNORE, "corners never take clicks") + check(content.get_parent().get_parent() == frame, "content still sits in the inner panel") + frame.free() diff --git a/godot-jev/tests/test_room_fx.gd.uid b/godot-jev/tests/test_room_fx.gd.uid new file mode 100644 index 0000000..4bcda88 --- /dev/null +++ b/godot-jev/tests/test_room_fx.gd.uid @@ -0,0 +1 @@ +uid://dpmcq1k5jojt2 diff --git a/godot-jev/tools/paint_rooms.gd b/godot-jev/tools/paint_rooms.gd index e2cde9e..b0e8597 100644 --- a/godot-jev/tools/paint_rooms.gd +++ b/godot-jev/tools/paint_rooms.gd @@ -9,6 +9,7 @@ extends SceneTree ## Replace any PNG in demo/art/ with hand-made art of the same name and size. const World := preload("res://demo/world.gd") +const RoomFx := preload("res://demo/room_fx.gd") const W := 160 const H := 90 # The back wall's rectangle; everything else is perspective toward it. @@ -27,10 +28,20 @@ const RAMPS := { "bone": ["14100c", "3b3228", "6b5d4a", "9c8b6e", "cbbd9c", "efe6cc"], "rust": ["140806", "3a160d", "662814", "8f3f1c", "b8622e", "d98f4e"], "gold": ["1a1004", "4a2f06", "86570b", "c08a17", "efc13a", "fff27a"], - "flame": ["3a0e04", "8a2a06", "d65a0e", "f59a1c", "ffd24a", "fff6c0"], + "flame": RoomFx.FLAME, # the game flickers pixels in exactly these colours "ruby": ["1a0308", "4a0a16", "8a1628", "c82d3c", "f06a6a", "ffc0b0"], "moss": ["0a1208", "1a2a14", "2e4422", "4a6a30", "739444", "a8c060"], + "cloth": ["0c0610", "261028", "44183e", "6a2450", "94385e", "c05a6a"], + "stone_warm": ["120b0c", "2b1c1c", "4d3229", "7a5036", "ad7a4c", "e0b273"], + "floor_warm": ["0e0908", "22160f", "3c2717", "5e3f22", "8c6232", "c09050"], + "wood_warm": ["160a06", "3a1a0c", "652f14", "96501f", "c47a30", "f0aa50"], } +## Ramps that swap to a warm twin where firelight dominates. The swap is +## dithered, so pools of torchlight get a warm edge instead of a hard line. +const WARM := {"stone": "stone_warm", "floor": "floor_warm", "wood": "wood_warm"} +## How far Bayer dithering reaches around each step: 1.0 dithers everywhere, +## lower values leave flat bands with dithered edges, which reads cleaner. +const DITHER := 0.6 const BAYER := [ [0.0, 8.0, 2.0, 10.0], [12.0, 4.0, 14.0, 6.0], [3.0, 11.0, 1.0, 9.0], [15.0, 7.0, 13.0, 5.0], @@ -46,12 +57,13 @@ const INK := { "e": ["ruby", 0.6, false], "E": ["ruby", 0.95, true], "f": ["flame", 0.55, true], "F": ["flame", 0.8, true], "X": ["flame", 1.0, true], "m": ["moss", 0.5, false], + "c": ["cloth", 0.55, false], "C": ["cloth", 0.8, false], } const SKELETON := [ "....BBBBB....", "...BwwwwwB...", - "...wkkwkkw...", + "...wkEwkEw...", "...BwwkwwB...", "....BwwwB....", ".....bkb.....", @@ -78,7 +90,9 @@ const BONES := [ ".BbrRrRrbw.......", ] const BRAZIER := [ - "...f.X..f....", + ".....f.......", + "...f.F..f....", + "...FfXf.F....", "..fFXXFXFf...", ".fFXXXXXXFf..", "IiiiiiiiiiiiI", @@ -91,12 +105,15 @@ const BRAZIER := [ "...iiiiii....", ] const SCONCE := [ - ".X.", - "XFX", - "fFf", - ".O.", - "iIi", - ".i.", + "..f..", + ".fXf.", + ".FXF.", + "fFXFf", + ".fFf.", + ".OoO.", + "iIIIi", + "..i..", + "..i..", ] const SKULL := [ ".bBb.", @@ -104,23 +121,85 @@ const SKULL := [ "kwkwk", ".bwb.", ] +const BANNER := [ + "iIIIIIIIi", + ".CcccccC.", + ".ccccccc.", + ".cccgccc.", + ".ccgGgcc.", + ".cgGYGgc.", + ".ccgGgcc.", + ".cccgccc.", + ".ccccccc.", + ".ccccccc.", + ".ccccccc.", + ".ccccccc.", + ".cc.ccc..", + ".c...cc..", + "......c..", +] +const RACK := [ + "oO.................Oo", + "oOOOOOOOOOOOOOOOOOOOo", + "oO.I.....iii......gOo", + "oO.I....iIIi......oOo", + "oO.I....iIIi.o...iiiO", + "oO.o.....io..o...IiOo", + "oO.o......o..o...IiOo", + "oO.o......o..o...IiOo", + "oO.o......o..o...IiOo", + "oO.o......o..o...IiOo", + "oO.o......o..o...IiOo", + "oO.o......o..o...IiOo", + "oOOOOOOOOOOOOOOOOOOOo", + "oO.o......o..o...IiOo", + "oO.o......o..o...IiOo", + "oO.o......o..o...IiOo", + "oO.o......o..o....iOo", + "oO.o......o..o.....Oo", + "oO.o......o..o.....Oo", + "oOOOOOOOOOOOOOOOOOOOo", + "oO.................Oo", + "oO.................Oo", +] +const CRATE := [ + "OOOOOOOOOOOO", + "OooooooooooO", + "OoOooooooOoO", + "OooOooooOooO", + "OoooOooOoooO", + "OooooOOooooO", + "OooooOOooooO", + "OoooOooOoooO", + "OooOooooOooO", + "OoOooooooOoO", + "OooooooooooO", + "OOOOOOOOOOOO", +] const CHEST := [ - ".oOOOOOOOOOOOo.", - "oOoooooooooooOo", - "IiiiiiiGiiiiiiI", - "oOooooGYGooooOo", - "oOoooooGoooooOo", - "oOoooooooooooOo", - "IiiiiiiiiiiiiiI", - "oooooooooooooo.", + "..oOOOOOOOOOOOOOOo..", + ".oOoooooooooooooOOo.", + "oOooooooooooooooooOo", + "IiiiiiiiiiiiiiiiiiiI", + "GgYgGgGYgGgYgGgGYgGg", + "gYGgYGgGGYgGgYGgGgYG", + "IiiiiiiiiGGiiiiiiiiI", + "oOoooooooGYgoooooOoo", + "oOooooooooGooooooOoo", + "oOoooooooooooooooOoo", + "oOoooooooooooooooOoo", + "IiiiiiiiiiiiiiiiiiiI", + "ooooooooooooooooooo.", ] const CROWN := [ - ".Y...Y...Y.", - ".G..GYG..G.", - ".GG.GGG.GG.", - ".GGGGGGGGG.", - ".GEGGEGGEG.", - ".ggggggggg.", + "..Y....Y....Y..", + "..G...GYG...G..", + "..GG..GGG..GG..", + "..GGG.GGG.GGG..", + "..GGGGGGGGGGG..", + "..GYGGEGGGEGYG.", + "..GEGGGEGGGEGG.", + "..ggggggggggg..", ] const SHIELD := [ "..rrr..", @@ -135,6 +214,7 @@ const SHIELD := [ var ramp: Array = [] # per pixel: ramp name var tone: Array = [] # per pixel: 0..1 before lighting var glow: Array = [] # per pixel: ignores lighting +var ao: Array = [] # per pixel: occlusion, multiplies the tone var lights: Array = [] # [x, y, radius, strength] var ambient := 0.2 @@ -163,67 +243,85 @@ func _paint(art_name: String, exits: Dictionary) -> Image: _shell("stone", "floor") _doorways(exits, {"north": "gate"}) _rubble() - _sprite(BRAZIER, 30, 62) - _light(36, 62, 90, 1.2) - _light(115, 105, 110, 0.5) + _shade(36, 73, 9, 2, 0.6) + _sprite(BRAZIER, 30, 60) + _light(36, 60, 90, 1.2) + _light(125, 100, 90, 0.9, false) _steps() "hall", "hall_cleared": ambient = 0.15 _shell("stone", "floor") _doorways(exits, {}) - _sprite(SCONCE, 56, 28) - _sprite(SCONCE, 102, 28) - _light(57, 28, 55, 0.9) - _light(103, 28, 55, 0.9) + _banner(47, T + 3) + _banner(W - 57, T + 3) + _sprite(SCONCE, 58, 25) + _sprite(SCONCE, 97, 25) + _light(60, 26, 55, 0.9) + _light(99, 26, 55, 0.9) + _light(4, 45, 40, 0.45, false) + _light(W - 4, 45, 40, 0.45, false) if art_name == "hall": + _shade(80, 61, 7, 1.5, 0.7) _sprite(SKELETON, 74, 42) - _light(80, 70, 40, 0.3) + _light(80, 70, 40, 0.3, false) else: + _shade(80, 58, 9, 2, 0.5) _sprite(BONES, 72, 55) - _light(80, 100, 90, 0.35) - _pillar(-3) - _pillar(W - 9) + _light(80, 100, 90, 0.35, false) + _pillar(-3, 1) + _pillar(W - 9, -1) "armory": _shell("stone", "floor") _doorways(exits, {}) - _rack(60, 24) - _rack(84, 24) - _sprite(SHIELD, 50, 36) - _sprite(SHIELD, 103, 36) - _sprite(SCONCE, 78, 16) - _light(79, 16, 90, 1.0) - _light(80, 100, 90, 0.35) - _barrel(126, 58) + _shade(80, 60, 26, 2, 0.5) + _sprite(RACK, 58, 26) + _sprite(RACK, 81, 26) + _sprite(SHIELD, 49, 34) + _sprite(SHIELD, 104, 34) + _sprite(SCONCE, 78, 13) + _light(80, 15, 90, 1.0) + _light(80, 100, 90, 0.35, false) + _shade(137, 82, 13, 3, 0.6) + _sprite(CRATE, 128, 70) + _barrel(123, 60) "ossuary": ambient = 0.03 _shell("stone", "floor") _doorways(exits, {}) for row in 5: for col in 11: - _sprite(SKULL, L + 2 + col * 6 + (row % 2) * 3, T + 2 + row * 6) + var x := L + 2 + col * 6 + (row % 2) * 3 + var y := T + 2 + row * 6 + for dy in range(-1, 5): + for dx in range(-1, 6): + _put(x + dx, y + dy, "stone", 0.12) + _sprite(SKULL, x, y) _altar() _light(80, 78, 115, 1.2) "antechamber": ambient = 0.12 _shell("stone", "floor", 0.8) _doorways(exits, {"north": "black_door"}) - _sprite(SCONCE, 22, 30) - _sprite(SCONCE, W - 25, 30) - _light(23, 30, 70, 1.0) - _light(W - 24, 30, 70, 1.0) - _light(80, 90, 80, 0.45) + _sprite(SKULL, 78, T + 1) + _sprite(SCONCE, 21, 27) + _sprite(SCONCE, W - 26, 27) + _light(23, 28, 70, 1.0) + _light(W - 24, 28, 70, 1.0) + _light(80, 90, 80, 0.45, false) "vault": ambient = 0.25 _shell("stone", "floor") _doorways(exits, {}) _coins() - _sprite(CHEST, 44, 64) - _sprite(CHEST, W - 59, 64) + _shade(52, 77, 13, 2, 0.6) + _shade(W - 52, 77, 13, 2, 0.6) + _sprite(CHEST, 42, 64) + _sprite(CHEST, W - 62, 64) _plinth() - _sprite(CROWN, 75, 35) - _light(80, 40, 70, 1.0) - _light(50, 70, 45, 0.6) - _light(W - 50, 70, 45, 0.6) + _sprite(CROWN, 73, 34) + _light(80, 38, 60, 0.8) + _light(52, 64, 40, 0.6) + _light(W - 52, 64, 40, 0.6) _: push_error("no painter for %s" % art_name) _shell("stone", "floor") @@ -237,6 +335,8 @@ func _reset() -> void: ramp.resize(W * H) tone.resize(W * H) glow.resize(W * H) + ao.resize(W * H) + ao.fill(1.0) ramp.fill("stone") tone.fill(0.0) glow.fill(false) @@ -250,10 +350,25 @@ func _put(x: int, y: int, ramp_name: String, t: float, glows := false) -> void: ramp[y * W + x] = ramp_name tone[y * W + x] = clampf(t, 0.0, 1.0) glow[y * W + x] = glows + ao[y * W + x] = 1.0 + + +## A light at (x, y). Firelight is warm and tints the ramps in WARM; cool +## light (daylight, the dark's own dim glow) keeps them cold. +func _light(x: float, y: float, radius: float, strength: float, warm := true) -> void: + lights.append([x, y, radius, strength, warm]) -func _light(x: float, y: float, radius: float, strength: float) -> void: - lights.append([x, y, radius, strength]) +## Darkens what's already painted around (x, y): contact shadows under props +## and the corners where walls meet. +func _shade(cx: float, cy: float, rx: float, ry: float, depth: float) -> void: + for y in range(floori(cy - ry), ceili(cy + ry) + 1): + for x in range(floori(cx - rx), ceili(cx + rx) + 1): + if x < 0 or y < 0 or x >= W or y >= H: + continue + var d := Vector2((x - cx) / rx, (y - cy) / ry).length() + if d < 1.0: + ao[y * W + x] *= 1.0 - depth * (1.0 - d * d) func _noise(x: int, y: int) -> float: @@ -294,6 +409,42 @@ func _shell(wall: String, floor_ramp: String, wall_tone := 1.0) -> void: var cell := _ceiling_cell(x, y) var seam := cell != _ceiling_cell(x, y + 1) or cell != _ceiling_cell(x - 1, y) _put(x, y, wall, 0.12 if seam else 0.32) + ao[y * W + x] = _corner_shadow(x, y, side_x) + _ribs(wall, wall_tone) + + +## Transverse ribs across the vault, each carried down the side walls as a +## pilaster, so the room reads as a run of bays rather than a box. +func _ribs(wall: String, wall_tone: float) -> void: + for side_x: int in [4, 36]: + var width := 2 + (L - side_x) / 12 + for i in width: + for x: int in [side_x + i, W - 1 - side_x - i]: + var edge := i == 0 or i == width - 1 + for y in range(0, ceili(_bottom_edge(side_x + i))): + var t := (0.62 if edge else 0.78) + 0.08 * _noise(x, y / 4) + if y < _top_edge(side_x + i): + t -= 0.1 + _put(x, y, wall, t * wall_tone) + var top := _top_edge(side_x) + for y in range(floori(top - width / 2.0), ceili(top + 1)): + for x in range(side_x + width, W - side_x - width): + _put(x, y, wall, (0.5 if y == floori(top - width / 2.0) else 0.66) * wall_tone) + for y in range(ceili(top + 1), ceili(top + 2)): + for x in range(side_x + width, W - side_x - width): + ao[y * W + x] *= 0.6 + + +## Light falls off into the seams where walls, floor and ceiling meet. +func _corner_shadow(x: int, y: int, side_x: int) -> float: + var seam := 99.0 + if side_x < 0: + seam = minf(absf(y - (B - 0.5)), absf(y - (T - 0.5))) + if y >= T and y < B: + seam = minf(seam, minf(x - L + 0.5, R - x + 0.5)) + else: + seam = minf(absf(y - _bottom_edge(side_x)), absf(y - _top_edge(side_x))) + return 1.0 - 0.4 * clampf(1.0 - seam / 4.0, 0.0, 1.0) func _back_cell(x: int, y: int) -> Vector2i: @@ -368,9 +519,12 @@ func _arch(style: String) -> void: _put(x, int(spring) + 1, "iron", 0.9) if style == "black_door": _sprite(["IIII", "IkkI", "IIkI", ".IkI", ".II."], int(VX) + 3, 44) - _light(VX + 5, 46, 10, 0.6) + _light(VX + 5, 46, 10, 0.6, false) +## A passage through a side wall: a stone frame, the far jamb's face (the +## wall's thickness, turned toward the viewer), and a floor running into the +## dark. func _side_opening(right: bool) -> void: for side_x in range(12, 30): var top := _top_edge(side_x) @@ -379,7 +533,19 @@ func _side_opening(right: bool) -> void: for y in range(floori(open_top) - 2, ceili(bottom)): var x := W - 1 - side_x if right else side_x var frame := side_x < 14 or side_x > 27 or y < open_top - _put(x, y, "stone", 0.8 + 0.1 * _noise(side_x, y / 3) if frame else 0.03) + if frame: + _put(x, y, "stone", 0.8 + 0.1 * _noise(side_x, y / 3)) + elif side_x > 23: + var course := (y - floori(open_top)) % 4 == 0 + _put(x, y, "stone", 0.35 if course else 0.62 + 0.08 * _noise(side_x, y / 4)) + elif y > bottom - 3: + _put(x, y, "floor", 0.18 - 0.05 * (bottom - y)) + else: + var depth := (side_x - 14) / 10.0 + _put(x, y, "stone", 0.02 + 0.05 * depth * depth) + if side_x == 14 or side_x == 23: + for y in range(floori(open_top), ceili(bottom)): + ao[y * W + (W - 1 - side_x if right else side_x)] *= 0.7 # --- props -------------------------------------------------------------------- @@ -394,85 +560,148 @@ func _sprite(rows: Array, x: int, y: int) -> void: _put(x + dx, y + dy, ink[0], ink[1], ink[2]) -func _pillar(x0: int) -> void: - for y in range(0, 86): - for dx in range(-1, 13): - var core := dx >= 1 and dx <= 10 - var cap := y < 5 or y > 79 - if not core and not cap: +## A round pillar in the foreground, darker than the room behind it with a +## bright rim on the side facing the light: +1 when light comes from its +## right, -1 from its left. +func _pillar(x0: int, lit_side: int) -> void: + for y in range(0, H): + var cap := y < 6 or y > 80 + for dx in range(-1, 14 if cap else 12): + if not cap and (dx < 1 or dx > 10): continue - var round := 1.0 - absf(dx - 5.0) / 7.0 - var crack := dx == 4 + (y / 7) % 3 and y > 20 and y < 55 - _put(x0 + dx, y, "stone", 0.25 if crack else 0.35 + 0.55 * round) + var u := (dx - 5.5) / 5.5 * lit_side + var t := 0.3 + 0.25 * u + if u > 0.8: + t = 0.95 + elif absf(u - 0.35) < 0.1: + t = 0.55 + if cap: + t = 0.9 if y == 5 or y == 81 else t + 0.1 + elif dx == 4 + (y / 7) % 3 and y > 20 and y < 55: + t = 0.1 + _put(x0 + dx, y, "stone", t) -func _rack(x0: int, y0: int) -> void: - for dx in 18: - _put(x0 + dx, y0 + 3, "wood", 0.7) - _put(x0 + dx, y0 + 14, "wood", 0.6) - for post in [0, 17]: - for dy in 26: - _put(x0 + post, y0 + dy, "wood", 0.5) - for peg in [4, 8, 12]: - for dy in range(4, 13): - _put(x0 + peg, y0 + dy, "rust" if peg != 8 else "iron", 0.5 if dy % 4 else 0.7) +func _banner(x: int, y: int) -> void: + _sprite(BANNER, x, y) + _shade(x + 4.5, y + 8, 6, 9, 0.25) func _barrel(x0: int, y0: int) -> void: + _shade(x0 + 7, y0 + 18, 11, 3, 0.6) for dy in 18: var bulge := 1 if dy > 3 and dy < 14 else 0 for dx in range(-bulge, 14 + bulge): - var band := dy == 3 or dy == 14 - _put(x0 + dx, y0 + dy, "iron" if band else "wood", 0.6 if band else 0.35 + 0.35 * (1.0 - absf(dx - 6.5) / 8.0)) + var band := dy == 2 or dy == 3 or dy == 14 or dy == 15 + var u := (dx - 6.5) / 8.0 + var shade := 0.3 + 0.55 * clampf(1.0 - absf(u + 0.25), 0.0, 1.0) + if band: + _put(x0 + dx, y0 + dy, "iron", shade + 0.15) + elif (dx + 1) % 4 == 0: + _put(x0 + dx, y0 + dy, "wood", shade - 0.15) + else: + _put(x0 + dx, y0 + dy, "wood", shade) + for dx in range(1, 13): + _put(x0 + dx, y0, "wood", 0.3) func _rubble() -> void: - for i in 70: - var x := W - 45 + floori(_noise(i, 3) * 40) - var y := 70 + floori(_noise(i, 9) * 18) - var size := 1 + floori(_noise(i, 5) * 3) - for dy in size: - for dx in size + 1: - _put(x + dx, y + dy, "stone", 0.6 + 0.35 * _noise(i, dy) - 0.1 * dy) - for i in 12: - _put(W - 40 + floori(_noise(i, 11) * 34), 68 + floori(_noise(i, 13) * 20), "moss", 0.6) + _shade(W - 26, 80, 30, 10, 0.5) + for i in 18: + var r := 2.5 + _noise(i, 5) * 4.5 + var cx := W - 48 + _noise(i, 3) * 44 + var cy := 70 + _noise(i, 9) * 16 - r * 0.3 + _boulder(cx, cy, r, 0.55 + 0.3 * _noise(i, 7)) + for i in 16: + _put(W - 44 + floori(_noise(i, 11) * 40), 66 + floori(_noise(i, 13) * 22), "moss", 0.5 + 0.3 * _noise(i, 17)) + + +## A rough round stone lit from the upper left. +func _boulder(cx: float, cy: float, r: float, t: float) -> void: + for y in range(floori(cy - r), ceili(cy + r) + 1): + for x in range(floori(cx - r), ceili(cx + r) + 1): + var d := Vector2(x - cx, (y - cy) * 1.2) + if d.length() > r + 0.3 * _noise(x, y): + continue + var facing := -(d.x + d.y) / (r * 1.4) + var edge := d.length() > r - 1.0 + _put(x, y, "stone", t + 0.3 * facing - (0.15 if edge else 0.0)) func _steps() -> void: for step in 2: var y0 := H - 6 + step * 3 for x in W: + var worn := 1.0 - absf(x - VX) / VX for dy in 3: - _put(x, y0 + dy, "stone", 0.9 if dy == 0 else 0.4 - 0.1 * step) + var t := 0.85 + 0.1 * worn if dy == 0 else 0.35 - 0.1 * step + 0.05 * _noise(x / 3, step) + _put(x, y0 + dy, "stone", t) + if dy == 2: + ao[(y0 + dy) * W + x] *= 0.6 func _altar() -> void: - for y in range(46, 62): - for x in range(64, 97): - var top := y < 49 - _put(x, y, "stone", 0.9 if top else 0.55 + 0.1 * _noise(x / 4, y / 4)) + _shade(80, 62, 22, 3, 0.7) + for y in range(44, 62): + for x in range(62, 99): + var slab := y < 48 + if slab: + var t := 0.95 if y == 44 else (0.6 if y == 47 else 0.8) + _put(x, y, "stone", t) + elif x >= 64 and x < 97: + var u := absf(x - 80.5) + var carved := (u < 5 and (y == 51 or y == 57)) or (absf(u - 5) < 0.6 and y > 51 and y < 57) + var cross := u < 1 and y > 49 and y < 59 or (y == 52 and u < 3) + var t := 0.35 if cross or carved else 0.55 + 0.1 * _noise(x / 4, y / 4) + if x == 64 or x == 96: + t -= 0.15 + _put(x, y, "stone", t) + for bone in [[68, 42], [88, 42]]: + _sprite(SKULL, bone[0], bone[1]) func _plinth() -> void: - for y in range(41, 63): - var inset := 0 if y < 44 or y > 58 else 2 - for x in range(71 + inset, 89 - inset): - _put(x, y, "stone", 0.85 if y < 44 else 0.6 + 0.2 * (1.0 - absf(x - 79.5) / 9.0)) + _shade(80, 63, 14, 3, 0.7) + for y in range(42, 63): + var cap := y < 45 or y > 59 + var inset := 0 if cap else 2 + for x in range(70 + inset, 91 - inset): + var u := (x - 80.0) / 10.0 + var t := 0.7 if y == 42 else (0.55 if cap else 0.3 + 0.3 * (1.0 - absf(u + 0.3))) + if not cap and (x - 70) % 5 == 0: + t -= 0.1 + _put(x, y, "stone", t) func _coins() -> void: - for pile in [[22, 76, 22], [W - 22, 76, 22]]: - for y in range(pile[1] - 9, H): + for pile in [[20, 78, 24], [W - 20, 78, 24]]: + _shade(pile[0], H - 2, pile[2] + 4, 4, 0.5) + for y in range(pile[1] - 11, H): for x in range(pile[0] - pile[2], pile[0] + pile[2]): var height: float = 1.0 - absf(x - pile[0]) / pile[2] - if y > pile[1] - height * 9.0 + _noise(x, 1) * 2.0: - var coin := _noise(x, y) > 0.8 - _put(x, y, "gold", 0.95 if coin else 0.35 + 0.35 * height - 0.15 * _noise(y, x)) - for i in 60: - var x := 50 + floori(_noise(i, 21) * 60) - var y := B + 2 + floori(_noise(i, 23) * (H - B - 4)) - _put(x, y, "gold", 0.9) - _put(x + 1, y, "gold", 0.55) + var surface: float = pile[1] - height * 11.0 + _noise(x, 1) * 1.5 + if y < surface: + continue + var t := 0.3 + 0.35 * height - 0.2 * clampf((y - surface) / 12.0, 0.0, 1.0) + if y < surface + 1.0: + t += 0.25 + var n := _noise(x / 2, y) + if n > 0.86: + t = 0.95 + elif n > 0.8: + t += 0.2 + _put(x, y, "gold", t) + for i in 5: + var gx: int = pile[0] - 12 + floori(_noise(i, pile[0]) * 24) + var gy: int = pile[1] - 4 + floori(_noise(pile[0], i) * 8) + _put(gx, gy, "ruby", 0.95, true) + _put(gx + 1, gy, "ruby", 0.6) + for i in 50: + var x := 44 + floori(_noise(i, 21) * 72) + var y := B + 3 + floori(_noise(i, 23) * (H - B - 6)) + _put(x, y, "gold", 0.95) + _put(x + 1, y, "gold", 0.6) + _put(x, y + 1, "gold", 0.3) # --- lighting ------------------------------------------------------------------- @@ -482,20 +711,33 @@ func _render() -> Image: for y in H: for x in W: var i := y * W + x - var colors: Array = RAMPS[ramp[i]] - var brightness: float = tone[i] + var ramp_name: String = ramp[i] + var brightness: float = tone[i] * ao[i] + var threshold: float = (BAYER[y % 4][x % 4] + 0.5) / 16.0 if not glow[i]: - brightness *= _lit(x, y) - var step: float = brightness * (colors.size() - 1) + (BAYER[y % 4][x % 4] + 0.5) / 16.0 - 0.5 + var lit := _lit(x, y) + brightness *= lit.x + if WARM.has(ramp_name) and lit.y > threshold: + ramp_name = WARM[ramp_name] + var colors: Array = RAMPS[ramp_name] + var step: float = brightness * (colors.size() - 1) + (threshold - 0.5) * DITHER var index := clampi(roundi(step), 0, colors.size() - 1) image.set_pixel(x, y, Color(colors[index])) return image -func _lit(x: int, y: int) -> float: +## Returns (light, warmth): how lit the pixel is, and how much of that light +## is firelight, eased so warmth fades out before the light does. +func _lit(x: int, y: int) -> Vector2: var light := ambient + var warm := 0.0 for l in lights: var d := Vector2(x - l[0], (y - l[1]) * 1.3).length() / float(l[2]) - light += l[3] * pow(maxf(0.0, 1.0 - d), 1.5) + var add: float = l[3] * pow(maxf(0.0, 1.0 - d), 1.5) + light += add + if l[4]: + warm += add var edge := Vector2((x - W / 2.0) / (W / 2.0), (y - H / 2.0) / (H / 2.0)).length() - return minf(light, 1.25) * (1.0 - 0.35 * clampf(edge - 0.6, 0.0, 1.0)) + var vignette := 1.0 - 0.35 * clampf(edge - 0.6, 0.0, 1.0) + var warmth := clampf((warm / light - 0.25) * 2.2, 0.0, 1.0) * clampf(warm * 3.0, 0.0, 1.0) + return Vector2(minf(light, 1.25) * vignette, warmth)