From f88baf1848326cd14391f8285f7ce3f02d0e0a92 Mon Sep 17 00:00:00 2001 From: Rob Kelly Date: Tue, 2 Sep 2025 19:12:40 -0600 Subject: [PATCH] Spawn animation for shambler beast --- .../animations/anim_emerge_floor.tres | 21 ++++- .../shambler_test/shambler_test.gd | 6 ++ .../shambler_test/shambler_test.tscn | 2 + .../visual_test/beast_spawner.gd | 14 ++++ .../visual_test/beast_spawner.gd.uid | 1 + .../visual_test/visual_test.gd | 16 ++++ .../visual_test/visual_test.gd.uid | 1 + .../visual_test/visual_test.tscn | 82 +++++++++++++++++-- src/world/grunk_beast/grunk_beast.gd | 5 +- src/world/grunk_beast/grunk_beast.tscn | 8 +- src/world/grunk_beast/shambler/shambler.tscn | 53 +----------- vault/elements/grunk beast.md | 2 +- 12 files changed, 149 insertions(+), 62 deletions(-) create mode 100644 levels/grunkbeast_test/visual_test/beast_spawner.gd create mode 100644 levels/grunkbeast_test/visual_test/beast_spawner.gd.uid create mode 100644 levels/grunkbeast_test/visual_test/visual_test.gd create mode 100644 levels/grunkbeast_test/visual_test/visual_test.gd.uid diff --git a/assets/npc/shambler/animations/anim_emerge_floor.tres b/assets/npc/shambler/animations/anim_emerge_floor.tres index 8e937c4..e65d259 100644 --- a/assets/npc/shambler/animations/anim_emerge_floor.tres +++ b/assets/npc/shambler/animations/anim_emerge_floor.tres @@ -395,14 +395,20 @@ tracks/55/path = NodePath(".") tracks/55/interp = 1 tracks/55/loop_wrap = true tracks/55/keys = { -"times": PackedFloat32Array(0, 2), -"transitions": PackedFloat32Array(1, 1), +"times": PackedFloat32Array(0, 0.0001, 2, 3.75), +"transitions": PackedFloat32Array(1, 1, 1, 1), "values": [{ "args": [], "method": &"_start_player_rumble" }, { "args": [], +"method": &"show" +}, { +"args": [], "method": &"_end_player_rumble" +}, { +"args": [], +"method": &"_on_spawn_animation_finished" }] } tracks/56/type = "value" @@ -453,3 +459,14 @@ tracks/59/keys = { "update": 0, "values": [0.0, 1.0] } +tracks/60/type = "method" +tracks/60/imported = false +tracks/60/enabled = true +tracks/60/path = NodePath("SpawnDebris") +tracks/60/interp = 1 +tracks/60/loop_wrap = true +tracks/60/keys = { +"times": PackedFloat32Array(), +"transitions": PackedFloat32Array(), +"values": [] +} diff --git a/levels/grunkbeast_test/shambler_test/shambler_test.gd b/levels/grunkbeast_test/shambler_test/shambler_test.gd index 8791468..60f6752 100644 --- a/levels/grunkbeast_test/shambler_test/shambler_test.gd +++ b/levels/grunkbeast_test/shambler_test/shambler_test.gd @@ -10,11 +10,17 @@ var target_velocity := Vector2.ZERO @onready var speed_label: Label = %SpeedLabel +func _ready() -> void: + model.play_spawn_animation() + + func _unhandled_input(event: InputEvent) -> void: if event.is_action("select_next_tool"): speed = min(speed + 0.1, 40) elif event.is_action("select_prev_tool"): speed = max(speed - 0.1, 0) + elif event.is_action("jump"): + model.play_spawn_animation() func _physics_process(delta: float) -> void: diff --git a/levels/grunkbeast_test/shambler_test/shambler_test.tscn b/levels/grunkbeast_test/shambler_test/shambler_test.tscn index 87f91c5..91663d7 100644 --- a/levels/grunkbeast_test/shambler_test/shambler_test.tscn +++ b/levels/grunkbeast_test/shambler_test/shambler_test.tscn @@ -22,11 +22,13 @@ id = "shambler_test" pretty_name = "Shambler Animation Testing Sandbox" [node name="FrameSkipper" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9, 0, -3) script = ExtResource("2_vtesn") frame_skip = 4 [node name="Shambler" parent="FrameSkipper" instance=ExtResource("2_56au4")] unique_name_in_owner = true +visible = false [node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] transform = Transform3D(0.866025, -0.156955, -0.474726, 0.5, 0.271854, 0.82225, 0, -0.949453, 0.31391, 0, 0, 0) diff --git a/levels/grunkbeast_test/visual_test/beast_spawner.gd b/levels/grunkbeast_test/visual_test/beast_spawner.gd new file mode 100644 index 0000000..366a0aa --- /dev/null +++ b/levels/grunkbeast_test/visual_test/beast_spawner.gd @@ -0,0 +1,14 @@ +extends Node3D + +@export var beast_scene: PackedScene + + +func spawn() -> void: + despawn() + var instance: Node3D = beast_scene.instantiate() + add_child(instance) + + +func despawn() -> void: + for c: Node in get_children(): + c.queue_free() diff --git a/levels/grunkbeast_test/visual_test/beast_spawner.gd.uid b/levels/grunkbeast_test/visual_test/beast_spawner.gd.uid new file mode 100644 index 0000000..572f076 --- /dev/null +++ b/levels/grunkbeast_test/visual_test/beast_spawner.gd.uid @@ -0,0 +1 @@ +uid://dyk5x48pdjejc diff --git a/levels/grunkbeast_test/visual_test/visual_test.gd b/levels/grunkbeast_test/visual_test/visual_test.gd new file mode 100644 index 0000000..e3fce31 --- /dev/null +++ b/levels/grunkbeast_test/visual_test/visual_test.gd @@ -0,0 +1,16 @@ +extends Level + +@onready var level: Node3D = %Level + + +func _clean_tree(node: Node) -> void: + if node is Gunkable: + (node as Gunkable).clear_all() + else: + for child: Node in node.get_children(): + _clean_tree(child) + + +func clean_all() -> void: + print("Cleaning all props in the scene...") + _clean_tree(level) diff --git a/levels/grunkbeast_test/visual_test/visual_test.gd.uid b/levels/grunkbeast_test/visual_test/visual_test.gd.uid new file mode 100644 index 0000000..e42d589 --- /dev/null +++ b/levels/grunkbeast_test/visual_test/visual_test.gd.uid @@ -0,0 +1 @@ +uid://c8lfvagqptams diff --git a/levels/grunkbeast_test/visual_test/visual_test.tscn b/levels/grunkbeast_test/visual_test/visual_test.tscn index d1bfbb4..828d439 100644 --- a/levels/grunkbeast_test/visual_test/visual_test.tscn +++ b/levels/grunkbeast_test/visual_test/visual_test.tscn @@ -1,6 +1,6 @@ -[gd_scene load_steps=88 format=4 uid="uid://700gr7k3gqlf"] +[gd_scene load_steps=93 format=4 uid="uid://700gr7k3gqlf"] -[ext_resource type="Script" uid="uid://68r4ht5ut1ct" path="res://src/game/level.gd" id="1_07ff1"] +[ext_resource type="Script" uid="uid://c8lfvagqptams" path="res://levels/grunkbeast_test/visual_test/visual_test.gd" id="1_f3alo"] [ext_resource type="ArrayMesh" uid="uid://c4klxlj1oop7t" path="res://assets/level/hallway/hallway_4.mesh" id="2_jle5o"] [ext_resource type="PackedScene" uid="uid://cdi5sl60mw1po" path="res://src/world/gunkable/gunkable.tscn" id="3_lpqtr"] [ext_resource type="Material" uid="uid://cqjr3cbxtfg2j" path="res://assets/materials/gunk_overlay.material" id="4_ibsng"] @@ -33,7 +33,9 @@ [ext_resource type="ArrayMesh" uid="uid://c2pruwilyqs07" path="res://assets/level/floor/floor_6x9.mesh" id="33_x7nmh"] [ext_resource type="Texture2D" uid="uid://ddjth5slpjrcd" path="res://assets/level/ceiling/ceiling_1_C.png" id="34_5w02r"] [ext_resource type="Texture2D" uid="uid://bs1fx1h0tddde" path="res://assets/level/ceiling/ceiling_1_M.png" id="35_hvv15"] +[ext_resource type="Script" uid="uid://deg5xd87cy8rg" path="res://src/props/interactive.gd" id="36_43u2e"] [ext_resource type="Texture2D" uid="uid://bmwmajwul60ti" path="res://assets/level/ceiling/ceiling_1_N.png" id="36_igk00"] +[ext_resource type="Script" uid="uid://dyk5x48pdjejc" path="res://levels/grunkbeast_test/visual_test/beast_spawner.gd" id="37_f3alo"] [ext_resource type="Texture2D" uid="uid://8hav47a84uk" path="res://assets/level/ceiling/ceiling_1_R.png" id="37_jfa7c"] [ext_resource type="ArrayMesh" uid="uid://bx00qgk2dyjrw" path="res://assets/level/wall/wall_2.mesh" id="38_as7yj"] @@ -358,8 +360,20 @@ turbulence_noise_strength = 0.1 turbulence_noise_scale = 0.3 turbulence_influence_min = 0.0 +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_hb05j"] +albedo_color = Color(0.866667, 0.109804, 0.101961, 1) + +[sub_resource type="SphereMesh" id="SphereMesh_8q52p"] +material = SubResource("StandardMaterial3D_hb05j") +radius = 0.2 +height = 0.2 +is_hemisphere = true + +[sub_resource type="SphereShape3D" id="SphereShape3D_clw2p"] +radius = 0.25 + [node name="VisualTest" type="Node3D"] -script = ExtResource("1_07ff1") +script = ExtResource("1_f3alo") id = "visual_test" pretty_name = "Visual Grunkbeast Test" @@ -376,6 +390,7 @@ godmode = true navigation_mesh = SubResource("NavigationMesh_n2727") [node name="Level" type="Node3D" parent="NavigationRegion3D"] +unique_name_in_owner = true [node name="Corridor" type="Node3D" parent="NavigationRegion3D/Level"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.2, 0, 12.3) @@ -3039,5 +3054,62 @@ process_material = SubResource("ParticleProcessMaterial_e530b") [node name="OverheadLight" parent="NavigationRegion3D/Level/Room4" instance=ExtResource("6_n2727")] transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 2.999, 0) -[node name="GrunkBeast" parent="NavigationRegion3D" instance=ExtResource("27_n2727")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 1.2, 9) +[node name="SpawnControl" type="Node3D" parent="NavigationRegion3D"] +transform = Transform3D(1, 0, 1.06581e-14, 0, 1, 0, -1.06581e-14, 0, 1, 6.2, -1.85, -7.45) + +[node name="Label3D" type="Label3D" parent="NavigationRegion3D/SpawnControl"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.74702, 0.3) +text = "Spawn Beast" + +[node name="ButtonMesh" type="MeshInstance3D" parent="NavigationRegion3D/SpawnControl"] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0.3, 0.25) +mesh = SubResource("SphereMesh_8q52p") +skeleton = NodePath("") + +[node name="InteractiveBody" type="StaticBody3D" parent="NavigationRegion3D/SpawnControl/ButtonMesh"] +collision_layer = 2 +collision_mask = 0 + +[node name="CollisionShape3D" type="CollisionShape3D" parent="NavigationRegion3D/SpawnControl/ButtonMesh/InteractiveBody"] +shape = SubResource("SphereShape3D_clw2p") + +[node name="Interactive" type="Node" parent="NavigationRegion3D/SpawnControl/ButtonMesh/InteractiveBody"] +script = ExtResource("36_43u2e") +enabled = true +label = "Level" +verb = "spawn beast" +metadata/_custom_type_script = "uid://deg5xd87cy8rg" + +[node name="CleanControl" type="Node3D" parent="NavigationRegion3D"] +transform = Transform3D(1, 0, 1.06581e-14, 0, 1, 0, -1.06581e-14, 0, 1, -9, 1, -1.45) + +[node name="Label3D" type="Label3D" parent="NavigationRegion3D/CleanControl"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.74702, 0.3) +text = "Clean" + +[node name="ButtonMesh" type="MeshInstance3D" parent="NavigationRegion3D/CleanControl"] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0.3, 0.25) +mesh = SubResource("SphereMesh_8q52p") +skeleton = NodePath("") + +[node name="InteractiveBody" type="StaticBody3D" parent="NavigationRegion3D/CleanControl/ButtonMesh"] +collision_layer = 2 +collision_mask = 0 + +[node name="CollisionShape3D" type="CollisionShape3D" parent="NavigationRegion3D/CleanControl/ButtonMesh/InteractiveBody"] +shape = SubResource("SphereShape3D_clw2p") + +[node name="Interactive" type="Node" parent="NavigationRegion3D/CleanControl/ButtonMesh/InteractiveBody"] +script = ExtResource("36_43u2e") +enabled = true +label = "Level" +verb = "clean all props" +metadata/_custom_type_script = "uid://deg5xd87cy8rg" + +[node name="BeastSpawner" type="Marker3D" parent="NavigationRegion3D"] +transform = Transform3D(0.866025, 0, 0.5, 0, 1, 0, -0.5, 0, 0.866025, 1.74509, -2, -2.64132) +script = ExtResource("37_f3alo") +beast_scene = ExtResource("27_n2727") + +[connection signal="activated" from="NavigationRegion3D/SpawnControl/ButtonMesh/InteractiveBody/Interactive" to="NavigationRegion3D/BeastSpawner" method="spawn"] +[connection signal="activated" from="NavigationRegion3D/CleanControl/ButtonMesh/InteractiveBody/Interactive" to="." method="clean_all"] diff --git a/src/world/grunk_beast/grunk_beast.gd b/src/world/grunk_beast/grunk_beast.gd index ca93a37..03fbb26 100644 --- a/src/world/grunk_beast/grunk_beast.gd +++ b/src/world/grunk_beast/grunk_beast.gd @@ -32,6 +32,7 @@ var traversing_link := false @onready var stalking_timer: Timer = %StalkingTimer @onready var blackboard: Blackboard = %Blackboard +@onready var behavior: BeehaveTree = %GrunkBeastBehavior #endregion @@ -41,6 +42,8 @@ var traversing_link := false func _ready() -> void: if play_spawn_animation: model.play_spawn_animation() + behavior.disable() + model.spawn_animation_finished.connect(behavior.enable) func is_pursuing() -> bool: @@ -115,7 +118,7 @@ func _physics_process(delta: float) -> void: func on_sound_detected(source: Vector3) -> void: # Check that the source isn't too far away, e.g. a sound from another room - if path_shorter_than(source, STALKING_SOUND_LIMIT): + if behavior.enabled and path_shorter_than(source, STALKING_SOUND_LIMIT): blackboard.set_value("stalking_target", source) stalking_timer.start() diff --git a/src/world/grunk_beast/grunk_beast.tscn b/src/world/grunk_beast/grunk_beast.tscn index 224d874..9dddbf4 100644 --- a/src/world/grunk_beast/grunk_beast.tscn +++ b/src/world/grunk_beast/grunk_beast.tscn @@ -42,7 +42,7 @@ radius = 1.4 radius = 20.0 [sub_resource type="SphereShape3D" id="SphereShape3D_oons1"] -radius = 3.0 +radius = 4.0 [sub_resource type="SphereShape3D" id="SphereShape3D_lak6w"] radius = 10.0 @@ -60,6 +60,7 @@ frame_skip = 3 [node name="Shambler" parent="FrameSkipper" instance=ExtResource("2_csisu")] unique_name_in_owner = true transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0) +visible = false time_scale_factor = 3.0 [node name="CollisionShape3D" type="CollisionShape3D" parent="."] @@ -125,6 +126,7 @@ wait_time = 40.0 one_shot = true [node name="GrunkBeastBehavior" type="Node" parent="." node_paths=PackedStringArray("blackboard", "actor")] +unique_name_in_owner = true script = ExtResource("6_d4ex2") blackboard = NodePath("../Blackboard") actor = NodePath("..") @@ -218,7 +220,7 @@ metadata/_custom_type_script = "uid://om57w2acvgb7" script = ExtResource("11_mbqcc") mean_time = 4.0 st_dev_time = 0.6 -wait_time = 4.75226 +wait_time = 3.05189 metadata/_custom_type_script = "uid://beyk2xtbjrsg4" [node name="RandomStalkingBehavior" type="Node" parent="GrunkBeastBehavior/StateSelector/StalkingSequence/RandomDelay"] @@ -264,7 +266,7 @@ metadata/_custom_type_script = "uid://cg016dbe7gs1x" script = ExtResource("11_mbqcc") mean_time = 5.0 st_dev_time = 1.0 -wait_time = 5.43146 +wait_time = 4.86324 metadata/_custom_type_script = "uid://beyk2xtbjrsg4" [node name="PickRandomLurkTarget" type="Node" parent="GrunkBeastBehavior/StateSelector/LurkSequence/RandomDelay"] diff --git a/src/world/grunk_beast/shambler/shambler.tscn b/src/world/grunk_beast/shambler/shambler.tscn index 2299707..fbbfb55 100644 --- a/src/world/grunk_beast/shambler/shambler.tscn +++ b/src/world/grunk_beast/shambler/shambler.tscn @@ -113,54 +113,6 @@ unique_name_in_owner = true transform = Transform3D(0.8, 0, 0, 0, 0.8, 0, 0, 0, 0.8, 0, 0, 0) top_level = true -[node name="Skeleton3D" parent="Armature" index="0"] -bones/1/position = Vector3(2.84217e-14, 1.51485, -2.51305) -bones/1/rotation = Quaternion(0.249313, 1.15445e-07, 2.97205e-08, 0.968423) -bones/1/scale = Vector3(1, 1, 1) -bones/2/rotation = Quaternion(0.204824, -2.09311e-13, 4.88339e-08, 0.978799) -bones/2/scale = Vector3(1, 1, 1) -bones/3/rotation = Quaternion(0.196821, 2.33752e-07, 9.3851e-08, 0.980439) -bones/4/rotation = Quaternion(0.0429047, 4.76413e-07, 5.11467e-08, 0.999079) -bones/5/scale = Vector3(1, 1, 1) -bones/6/rotation = Quaternion(-0.651315, 0.751756, -0.0947566, 0.0409037) -bones/7/rotation = Quaternion(0.50357, -0.0489935, -0.00100176, 0.862563) -bones/8/rotation = Quaternion(0.204939, -0.000834636, 0.0245877, 0.978466) -bones/9/rotation = Quaternion(0.651315, 0.751756, -0.0947566, -0.0409037) -bones/10/rotation = Quaternion(0.50357, 0.0489935, 0.00100176, 0.862563) -bones/11/rotation = Quaternion(0.204939, 0.000834638, -0.0245877, 0.978465) -bones/12/rotation = Quaternion(0.0338831, -0.281898, -0.795744, 0.534955) -bones/13/rotation = Quaternion(0.00213064, 0.0655049, -0.355854, 0.932241) -bones/14/rotation = Quaternion(-0.109452, 0.0150748, -0.151858, 0.982208) -bones/15/rotation = Quaternion(0.269235, -0.0369024, 0.847203, -0.456507) -bones/16/rotation = Quaternion(0.185658, -0.109653, -0.43151, 0.87596) -bones/17/rotation = Quaternion(-0.192939, 0.0499936, 0.0316556, 0.979425) -bones/18/rotation = Quaternion(0.0338831, 0.281898, 0.795744, 0.534955) -bones/19/rotation = Quaternion(0.00213072, -0.0655051, 0.355853, 0.932241) -bones/20/rotation = Quaternion(-0.109452, -0.0150747, 0.151858, 0.982208) -bones/21/rotation = Quaternion(-0.269235, -0.0369029, 0.847203, 0.456507) -bones/22/rotation = Quaternion(0.185658, 0.109653, 0.431509, 0.875961) -bones/23/rotation = Quaternion(-0.192939, -0.0499936, -0.0316556, 0.979425) -bones/24/position = Vector3(1.55329, 0.839106, 0.783253) -bones/24/rotation = Quaternion(0.508763, 0.508763, -0.491081, 0.491081) -bones/25/position = Vector3(0.428726, 0.847774, -1.16198) -bones/26/position = Vector3(-2.36554e-07, -1.66001e-07, 5.12588e-07) -bones/27/rotation = Quaternion(0.0793162, 0.0182055, -0.71141, 0.69805) -bones/28/position = Vector3(-1.55329, 0.839106, 0.783253) -bones/28/rotation = Quaternion(0.508763, -0.508763, 0.491081, 0.491081) -bones/29/position = Vector3(-0.428726, 0.847774, -1.16198) -bones/31/rotation = Quaternion(0.0793162, -0.0182055, 0.71141, 0.69805) -bones/32/position = Vector3(0.776177, 0.476268, -2.27135) -bones/33/position = Vector3(1.47158e-07, 3.29446e-07, -1.54669e-07) -bones/33/rotation = Quaternion(-0.19757, -0.580371, 0.78173, 0.114167) -bones/35/position = Vector3(-0.776177, 0.476268, -2.27135) -bones/36/position = Vector3(-5.46684e-07, 1.39751e-08, -2.09895e-07) -bones/36/rotation = Quaternion(0.19757, -0.580371, 0.78173, -0.114167) -bones/38/position = Vector3(0.737397, 0.515845, -3.26979) -bones/39/position = Vector3(-4.9934e-08, 2.2182e-07, -1.97891e-07) -bones/39/rotation = Quaternion(0.136442, -0.601968, 0.761522, -0.197743) -bones/41/position = Vector3(-0.737397, 0.515845, -3.26979) -bones/42/position = Vector3(3.2303e-07, 2.28217e-07, -7.45868e-09) - [node name="Shambler" parent="Armature/Skeleton3D" index="0"] surface_material_override/0 = ExtResource("2_nayyt") @@ -177,7 +129,7 @@ primary_limit_angle = 1.5708 primary_damp_threshold = 0.7 [node name="SleeveL" type="BoneAttachment3D" parent="Armature/Skeleton3D" index="2"] -transform = Transform3D(0.0438309, 7.45058e-08, -0.999039, 0.999039, 6.10948e-07, 0.0438309, 7.37607e-07, -1, -4.47035e-08, 1.63061, 0.0124229, 0.803842) +transform = Transform3D(0.0438309, -2.98023e-08, -0.999039, -0.998162, -0.0418897, -0.0437925, -0.0418495, 0.999122, -0.00183608, 0.214327, -0.0756478, -0.79725) bone_name = "Sleeve.L" bone_idx = 27 @@ -188,7 +140,7 @@ particle_scene = ExtResource("5_lqi3b") metadata/_custom_type_script = "uid://cuqr167olan8n" [node name="SleeveR" type="BoneAttachment3D" parent="Armature/Skeleton3D" index="3"] -transform = Transform3D(0.0438309, -7.45058e-08, 0.999039, -0.999039, 6.10948e-07, 0.0438309, -7.37607e-07, -1, -4.47035e-08, -1.63061, 0.0124234, 0.803842) +transform = Transform3D(0.0438309, 2.98023e-08, 0.999039, 0.998162, -0.0418897, -0.0437925, 0.0418495, 0.999122, -0.00183608, -0.214327, -0.0756484, -0.79725) bone_name = "Sleeve.R" bone_idx = 31 @@ -223,6 +175,7 @@ top_level = true transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10) [node name="DebugBall" type="MeshInstance3D" parent="LookTargetPivot/LookTarget" index="0"] +visible = false mesh = SubResource("SphereMesh_s7rwx") [node name="GPUParticlesCollisionBox3D" type="GPUParticlesCollisionBox3D" parent="." index="4"] diff --git a/vault/elements/grunk beast.md b/vault/elements/grunk beast.md index 7110b1d..6644279 100644 --- a/vault/elements/grunk beast.md +++ b/vault/elements/grunk beast.md @@ -3,7 +3,7 @@ tags: - lore - mechanics --- -A little fucking ghoulie!!! +A giant fucking ghoulie!!! Summoned when the [[grunk alert]] maxes out. Hunts down the player and grunkifies 'em.