Nachbesserungen aus der Gesamtprüfung von M1d

Das Lebensmoos bekommt links und rechts Platz für seinen Umriss, der
bei zwei von drei Formen abgeschnitten war; die Bilder der Vitrine sind
neu aufgenommen. Die Pausenanzeige kehrt zurück, wenn eine Meldung
während der Pause abläuft. Ein Test prüft die Splitter fremder
Schläge, und der Test ohne Bilderordner hängt nicht mehr davon ab, was
in res://art liegt. Der Fragebogen nennt die Felsproben und sagt, was
sofort kommt und was erst mit der Antwort des Hosts.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Steven Wroblewski
2026-10-02 14:36:43 +02:00
parent e53d296080
commit 417cf30a9c
10 changed files with 53 additions and 11 deletions
+4 -3
View File
@@ -6,6 +6,7 @@ M1d zeichnet das Spielfeld als Pixelgrafik aus Code, im Stil klassischer Farmspi
1. Doppelklick auf `play.bat`.
2. Im Menü auf „Stilproben ansehen“. Die Vitrine zeigt
- weichen und harten Fels und Grundgestein,
- toten und lebendigen Boden,
- Lebensmoos,
- eine Ranke, die Steine trägt,
@@ -16,7 +17,7 @@ M1d zeichnet das Spielfeld als Pixelgrafik aus Code, im Stil klassischer Farmspi
Mit 1, 2 und 3 oder den Knöpfen unten wechselst du den Stil, mit Esc oder „Zurück“ geht es ins Menü.
3. Im Spiel wechselt F2 den Stil. Lauf herum, schlag Stein und sieh dir Fels, Figur, Zielmarke und Splitter an. Das Spiel merkt sich den zuletzt gewählten Stil.
4. Zu zweit wie in M1c: Die Namen über den Figuren sind jetzt scharf, und dein eigener Schlag zeigt seine Splitter sofort, auch als Gast.
4. Zu zweit wie in M1c: Die Namen über den Figuren sind jetzt scharf, und dein eigener Schlag zeigt seine Splitter sofort, auch als Gast. Risse und das Brechen des Felses kommen weiter erst mit der Antwort des Hosts. Splitter fliegen bei jedem Schlag auf Fels, auch auf harten Fels und Grundgestein, die deine Steinspitzhacke noch nicht brechen kann.
So sehen die drei Proben aus:
@@ -30,10 +31,10 @@ So sehen die drei Proben aus:
1. Bleibt es bei Warm, oder gefällt dir im Spiel ein anderer Stil besser?
2. Was gefällt dir an deinem Favoriten am besten, und was stört dich daran?
3. Gibt es an den anderen beiden etwas, das du übernehmen möchtest, etwa das Leuchten des Lebendigen aus Glimmen?
4. Erkennst du auf einen Blick, was Boden, weicher Fels und harter Fels ist? Und was lebendiger Boden ist?
4. Erkennst du auf einen Blick, was Boden, weicher Fels, harter Fels und Grundgestein ist? Und was lebendiger Boden ist?
5. Wirkt das Lebendige lebendig: das Moos, die Ranke, die wachsende Pflanze, das Tier, die erwachende Ruine? Oder wirkt es nüchtern?
6. Ist die Bewegung angenehm: Laufen, Wiegen, Wachsen und Hüpfen? Oder ist es zu viel oder zu wenig?
7. Findest du deine Figur sofort, auch neben anderen? Sind Figuren und Dinge groß genug?
8. Wirkt ein Schlag als Gast jetzt sofort, und sind die Namen über den Figuren scharf?
8. Wirkt ein Schlag als Gast jetzt sofort, auch wenn Risse und Brechen erst mit der Antwort des Hosts kommen? Und sind die Namen über den Figuren scharf?
Antworte formlos im Chat oder als Kommentar in Gitea.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

+6 -5
View File
@@ -573,14 +573,15 @@ func _moss(canvas: CanvasItem, rect: Rect2, state: Dictionary) -> void:
var variant: int = state.get("variant", 0) % 3
var twinkle := int(float(state.get("time", 0.0)) * 2.5) % 4
var foot := Vector2(rect.get_center().x, rect.end.y)
_put(canvas, _image("moss/%d/%d" % [variant, twinkle], func() -> Pixels: return _moss_image(variant, twinkle)), foot - Vector2(8, 13))
_put(canvas, _image("moss/%d/%d" % [variant, twinkle], func() -> Pixels: return _moss_image(variant, twinkle)), foot - Vector2(10, 13))
## A cushion of moss whose spores twinkle one after another.
## A cushion of moss whose spores twinkle one after another, with room on
## both sides for its outline.
func _moss_image(variant: int, twinkle: int) -> Pixels:
var pixels := Pixels.new(TILE, 13)
var pixels := Pixels.new(TILE + 2, 13)
var shift := variant - 1
for bump: Vector4 in [Vector4(4.5 + shift, 9.5, 4, 3.2), Vector4(11, 9.2, 4.3, 3.5), Vector4(7.8 - shift, 6.8, 3.8, 3.4)]:
for bump: Vector4 in [Vector4(6.5 + shift, 9.5, 4, 3.2), Vector4(13, 9.2, 4.3, 3.5), Vector4(9.8 - shift, 6.8, 3.8, 3.4)]:
pixels.ellipse(bump.x, bump.y, bump.z, bump.w, _c("moss"))
for y in pixels.size.y:
for x in pixels.size.x:
@@ -591,7 +592,7 @@ func _moss_image(variant: int, twinkle: int) -> Pixels:
elif not pixels.filled(x, y - 1) or not pixels.filled(x, y - 2):
pixels.put(x, y, _c("moss_light"))
pixels.outline(_ink(_c("moss")), tinted_outlines)
var spores: Array[Vector2i] = [Vector2i(4 + shift, 8), Vector2i(8 - shift, 5), Vector2i(12, 8)]
var spores: Array[Vector2i] = [Vector2i(6 + shift, 8), Vector2i(10 - shift, 5), Vector2i(14, 8)]
for index in spores.size():
var at := spores[index]
var bright := index == twinkle
+5 -2
View File
@@ -10,6 +10,7 @@ var _message := Label.new()
var _status := Label.new()
var _help := Label.new()
var _message_left := 0.0
var _paused := false
func _ready() -> void:
@@ -34,7 +35,7 @@ func _process(delta: float) -> void:
return
_message_left -= delta
if _message_left <= 0.0:
_message.text = ""
_message.text = tr("PAUSED") if _paused else ""
func show_stone(count: int) -> void:
@@ -48,8 +49,10 @@ func flash(key: String, values: Array = []) -> void:
_message_left = MESSAGE_SECONDS
## Shows or hides the pause notice. It stays until the game continues.
## Shows or hides the pause notice. It stays until the game continues and
## returns when a message shown in between ends.
func show_paused(paused: bool) -> void:
_paused = paused
_message.text = tr("PAUSED") if paused else ""
_message_left = 0.0
+1 -1
View File
@@ -105,6 +105,6 @@ func test_a_picture_named_after_an_id_replaces_its_drawing() -> void:
func test_without_the_folder_of_pictures_everything_is_drawn() -> void:
var art := Art.new()
art.load_overrides(Art.OVERRIDE_DIR)
art.load_overrides("res://tests/no-pictures-here")
for id in Art.IDS:
check(not art.has_override(id), "no picture for %s" % id)
+13
View File
@@ -30,3 +30,16 @@ func test_the_status_line_stays_until_it_is_replaced() -> void:
check_eq(hud.message(), "", "the message is gone after a while")
check_eq(hud.status_text(), tr("STATUS_HOST") % [24680, 2], "the status line is not")
_free(hud)
func test_the_pause_notice_returns_after_a_message() -> void:
var hud := _hud()
hud.show_paused(true)
hud.flash("STYLE_SWITCHED", [tr("STYLE_PASTEL")])
hud._process(Hud.MESSAGE_SECONDS + 0.1)
check_eq(hud.message(), tr("PAUSED"), "still paused, the notice is back")
hud.show_paused(false)
hud.flash("SAVED")
hud._process(Hud.MESSAGE_SECONDS + 0.1)
check_eq(hud.message(), "", "without a pause the message just goes")
_free(hud)
+14
View File
@@ -479,3 +479,17 @@ func test_the_command_line_chooses_the_style() -> void:
_started.append(main)
check_eq(main.art.style.key(), PastelStyle.KEY, "the style of the command line")
_clean_up([directory])
func test_hits_of_other_players_show_their_bursts() -> void:
var directory := TestFiles.temporary_dir("other-hits")
var main := _start_main(directory)
main.play(false)
var rock: Vector2i = main.session.spawn_point() + Vector2i(7, -2)
var reports: Array[Dictionary] = [
{"type": "tile_hit", "player": main.session.local_player() + 1, "x": rock.x, "y": rock.y},
{"type": "tile_changed", "x": rock.x, "y": rock.y},
]
main._apply(reports)
check_eq(main.map_view.burst_count(), 2, "a hit and a breaking blow of another player")
_clean_up([directory])
+10
View File
@@ -57,3 +57,13 @@ func test_the_ruin_glows_in_its_doorway() -> void:
var light := style._ruin_glow().image
check(light.get_pixel(24, 31).a > 0.5, "bright in the middle of the doorway")
check_eq(light.get_pixel(3, 30).a, 0.0, "dark on the walls")
func test_moss_keeps_its_outline_on_both_sides() -> void:
var style := WarmStyle.new()
for variant in 3:
var image := style._moss_image(variant, 0).image
for y in image.get_height():
for x: int in [0, image.get_width() - 1]:
var pixel := image.get_pixel(x, y)
check(pixel.a == 0.0 or pixel == style.palette["outline"], "variant %d at %d, %d: %s" % [variant, x, y, pixel])