Et toujours du dev pour la béta

* Evolution de l'histoire avec de nouveaux dialogues, une plus grande durée de vie du jeu, des nouvelles zones d'histoire...
* Suppression du mode infini
* Ajout d'un écran des mutations découvertes
* Ajout d'un nouveau mécanisme de respawn situé dans le vaissau
* Ajout de 2 nouveaux modificateurs de région
* Quatre nouveaux artefacts
* Visuel de la décontamination de la planète 3D en cours de la partie
* Ajout d'une annonce visuelle des scène du jeu
* Fix sur la mutation Généreux pour être en accord avec sa description
* Amélioration de l'effet de la mutation Purification
* Fix de la mutation sociale aux niveau supérieurs
* Ajout d'un effet visuel de réacteur sur le joueur 3D
* Fix sur l'annonce de nouveaux objets qui se déclenchaient à une nouvelle run
* Amélioration des animation et des informations données dans le vaisseau
* Correction mineure des traductions
This commit is contained in:
2026-04-28 23:41:36 +02:00
parent 7ae362a3a5
commit 91e266ec85
269 changed files with 4393 additions and 1699 deletions
+168 -11
View File
@@ -1,17 +1,174 @@
[gd_scene format=3 uid="uid://dac5wte80dwj0"]
[ext_resource type="Script" uid="uid://bb44144ckt2w7" path="res://common/scene_manager/scripts/scene_manager.gd" id="1_1c0qu"]
[ext_resource type="Script" uid="uid://1ejbvr3431ac" path="res://common/scene_manager/scripts/scene.gd" id="2_c1lr7"]
[ext_resource type="Resource" uid="uid://bvksiaiocwob5" path="res://common/scene_manager/scenes/cockpit.tres" id="3_e28ni"]
[ext_resource type="Resource" uid="uid://bvgdq43fpl1xs" path="res://common/scene_manager/scenes/intro.tres" id="4_msho1"]
[ext_resource type="Resource" uid="uid://boqgwjyxyb45r" path="res://common/scene_manager/scenes/region.tres" id="5_ytog4"]
[ext_resource type="Resource" uid="uid://c27wenetitwm" path="res://common/scene_manager/scenes/region_selection.tres" id="6_chs32"]
[ext_resource type="Resource" uid="uid://diro74w272onp" path="res://common/scene_manager/scenes/title.tres" id="7_ol3d5"]
[ext_resource type="Resource" uid="uid://jegdqnd2sqi2" path="res://common/scene_manager/scenes/astra.tres" id="8_e28ni"]
[ext_resource type="Resource" uid="uid://b3ebbo88ptrrc" path="res://common/scene_manager/scenes/garage.tres" id="9_msho1"]
[ext_resource type="Resource" uid="uid://cvrs6qsq7mpa5" path="res://common/scene_manager/scenes/borea.tres" id="10_ytog4"]
[ext_resource type="Resource" uid="uid://cjoo5et437kr3" path="res://common/scene_manager/scenes/vending_machine_room.tres" id="11_chs32"]
[ext_resource type="FontFile" uid="uid://qt80w6o01q5s" path="res://gui/ressources/fonts/TitanOne-Regular.ttf" id="3_y08yd"]
[ext_resource type="Texture2D" uid="uid://d3k7rl7nbp7yx" path="res://common/icons/device-floppy.svg" id="12_hksyt"]
[sub_resource type="LabelSettings" id="LabelSettings_udn24"]
font = ExtResource("3_y08yd")
font_size = 50
[sub_resource type="Animation" id="Animation_hksyt"]
length = 0.001
tracks/0/type = "bezier"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("VBoxContainer/IconContainer:theme_override_constants/margin_left")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"handle_modes": PackedInt32Array(0),
"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0),
"times": PackedFloat32Array(0)
}
tracks/1/type = "bezier"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("VBoxContainer/TitleContainer:theme_override_constants/margin_left")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"handle_modes": PackedInt32Array(0),
"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0),
"times": PackedFloat32Array(0)
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath(".:visible")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("ColorRect:modulate:a")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [0.5]
}
[sub_resource type="Animation" id="Animation_1chpl"]
resource_name = "announce"
length = 1.2
tracks/0/type = "bezier"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("VBoxContainer/IconContainer:theme_override_constants/margin_left")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"handle_modes": PackedInt32Array(1, 0, 0),
"points": PackedFloat32Array(2000, 0, 0, 0, 0, 0, -0.9666667, 17.742292, 0.9666667, -17.742292, -2013.7502, 0, -13.750244, 0, 0),
"times": PackedFloat32Array(0, 0.6, 1.2)
}
tracks/1/type = "bezier"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("VBoxContainer/TitleContainer:theme_override_constants/margin_left")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"handle_modes": PackedInt32Array(1, 0, 0),
"points": PackedFloat32Array(-2000, 0, 0, 0, 0, 0, -0.93333334, 0, 0.93333334, 0, 2000, 0, 0, 0, 0),
"times": PackedFloat32Array(0, 0.56666666, 1.2)
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath(".:visible")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 1.1333334, 1.2),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 1,
"values": [true, true, false]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("ColorRect:modulate:a")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0, 0.25833333, 0.82500005, 1.2),
"transitions": PackedFloat32Array(1, 1, 1, 1),
"update": 0,
"values": [0.0, 0.5, 0.5, 0.0]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_e3yhc"]
_data = {
&"RESET": SubResource("Animation_hksyt"),
&"announce": SubResource("Animation_1chpl")
}
[node name="SceneManager" type="Node" unique_id=1630600782]
script = ExtResource("1_1c0qu")
scenes = Array[ExtResource("2_c1lr7")]([ExtResource("3_e28ni"), ExtResource("4_msho1"), ExtResource("5_ytog4"), ExtResource("6_chs32"), ExtResource("7_ol3d5"), ExtResource("8_e28ni"), ExtResource("9_msho1"), ExtResource("10_ytog4"), ExtResource("11_chs32")])
[node name="SceneAnnounce" type="CanvasLayer" parent="." unique_id=2098705893]
unique_name_in_owner = true
layer = 10
visible = false
[node name="ColorRect" type="ColorRect" parent="SceneAnnounce" unique_id=1450779057]
modulate = Color(1, 1, 1, 0.5)
custom_minimum_size = Vector2(0, 250)
anchors_preset = 14
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
offset_top = -125.0
offset_bottom = 125.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
color = Color(0.0627451, 0.05882353, 0.16862746, 1)
[node name="VBoxContainer" type="VBoxContainer" parent="SceneAnnounce" unique_id=954249153]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
alignment = 1
[node name="IconContainer" type="MarginContainer" parent="SceneAnnounce/VBoxContainer" unique_id=877483857]
layout_mode = 2
mouse_filter = 2
theme_override_constants/margin_left = 0
[node name="SceneIcon" type="TextureRect" parent="SceneAnnounce/VBoxContainer/IconContainer" unique_id=659833821]
unique_name_in_owner = true
custom_minimum_size = Vector2(80, 80)
layout_mode = 2
texture = ExtResource("12_hksyt")
expand_mode = 3
stretch_mode = 5
[node name="TitleContainer" type="MarginContainer" parent="SceneAnnounce/VBoxContainer" unique_id=2021413473]
layout_mode = 2
mouse_filter = 2
theme_override_constants/margin_left = 0
[node name="SceneTitle" type="Label" parent="SceneAnnounce/VBoxContainer/TitleContainer" unique_id=1280778170]
unique_name_in_owner = true
layout_mode = 2
text = "Ship"
label_settings = SubResource("LabelSettings_udn24")
horizontal_alignment = 1
vertical_alignment = 1
[node name="SceneAnnounceAnimationPlayer" type="AnimationPlayer" parent="SceneAnnounce" unique_id=186313985]
unique_name_in_owner = true
libraries/ = SubResource("AnimationLibrary_e3yhc")
-10
View File
@@ -1,10 +0,0 @@
[gd_resource type="Resource" script_class="Scene" format=3 uid="uid://jegdqnd2sqi2"]
[ext_resource type="Script" uid="uid://1ejbvr3431ac" path="res://common/scene_manager/scripts/scene.gd" id="1_114vb"]
[resource]
script = ExtResource("1_114vb")
scene_id = "ASTRA"
scene_path = "res://stages/3d_scenes/astra_base/astra_base.tscn"
mouse_captured = true
metadata/_custom_type_script = "uid://1ejbvr3431ac"
-10
View File
@@ -1,10 +0,0 @@
[gd_resource type="Resource" script_class="Scene" format=3 uid="uid://cvrs6qsq7mpa5"]
[ext_resource type="Script" uid="uid://1ejbvr3431ac" path="res://common/scene_manager/scripts/scene.gd" id="1_7m46k"]
[resource]
script = ExtResource("1_7m46k")
scene_id = "BOREA"
scene_path = "res://stages/3d_scenes/borea_base/borea_base.tscn"
mouse_captured = true
metadata/_custom_type_script = "uid://1ejbvr3431ac"
-10
View File
@@ -1,10 +0,0 @@
[gd_resource type="Resource" script_class="Scene" format=3 uid="uid://bvksiaiocwob5"]
[ext_resource type="Script" uid="uid://1ejbvr3431ac" path="res://common/scene_manager/scripts/scene.gd" id="1_tkiq8"]
[resource]
script = ExtResource("1_tkiq8")
scene_id = "COCKPIT"
scene_path = "res://stages/3d_scenes/cockpit_scene/cockpit_scene.tscn"
mouse_captured = true
metadata/_custom_type_script = "uid://1ejbvr3431ac"
-10
View File
@@ -1,10 +0,0 @@
[gd_resource type="Resource" script_class="Scene" format=3 uid="uid://b3ebbo88ptrrc"]
[ext_resource type="Script" uid="uid://1ejbvr3431ac" path="res://common/scene_manager/scripts/scene.gd" id="1_v8prw"]
[resource]
script = ExtResource("1_v8prw")
scene_id = "GARAGE"
scene_path = "res://stages/3d_scenes/ship_garage/ship_garage.tscn"
mouse_captured = true
metadata/_custom_type_script = "uid://1ejbvr3431ac"
-9
View File
@@ -1,9 +0,0 @@
[gd_resource type="Resource" script_class="Scene" load_steps=2 format=3 uid="uid://bvgdq43fpl1xs"]
[ext_resource type="Script" uid="uid://1ejbvr3431ac" path="res://common/scene_manager/scripts/scene.gd" id="1_6ws88"]
[resource]
script = ExtResource("1_6ws88")
scene_id = "INTRO"
scene_path = "res://stages/intro/intro.tscn"
metadata/_custom_type_script = "uid://1ejbvr3431ac"
-10
View File
@@ -1,10 +0,0 @@
[gd_resource type="Resource" script_class="Scene" load_steps=2 format=3 uid="uid://boqgwjyxyb45r"]
[ext_resource type="Script" uid="uid://1ejbvr3431ac" path="res://common/scene_manager/scripts/scene.gd" id="1_10qbh"]
[resource]
script = ExtResource("1_10qbh")
scene_id = "REGION"
scene_path = "res://stages/terrain/region/region.tscn"
need_terrain_generated = true
metadata/_custom_type_script = "uid://1ejbvr3431ac"
@@ -1,9 +0,0 @@
[gd_resource type="Resource" script_class="Scene" format=3 uid="uid://c27wenetitwm"]
[ext_resource type="Script" uid="uid://1ejbvr3431ac" path="res://common/scene_manager/scripts/scene.gd" id="1_smjh0"]
[resource]
script = ExtResource("1_smjh0")
scene_id = "REGION_SELECTION"
scene_path = "res://stages/region_selection/region_selection.tscn"
metadata/_custom_type_script = "uid://1ejbvr3431ac"
-10
View File
@@ -1,10 +0,0 @@
[gd_resource type="Resource" script_class="Scene" format=3 uid="uid://diro74w272onp"]
[ext_resource type="Script" uid="uid://1ejbvr3431ac" path="res://common/scene_manager/scripts/scene.gd" id="1_48g2j"]
[resource]
script = ExtResource("1_48g2j")
scene_id = "TITLE"
scene_path = "res://stages/title_screen/title_screen.tscn"
need_to_be_saved = false
metadata/_custom_type_script = "uid://1ejbvr3431ac"
@@ -1,10 +0,0 @@
[gd_resource type="Resource" script_class="Scene" format=3 uid="uid://cjoo5et437kr3"]
[ext_resource type="Script" uid="uid://1ejbvr3431ac" path="res://common/scene_manager/scripts/scene.gd" id="1_2xhcl"]
[resource]
script = ExtResource("1_2xhcl")
scene_id = "VENDING_MACHINE_ROOM"
scene_path = "res://stages/3d_scenes/vending_machine_room/vending_machine_room.tscn"
mouse_captured = true
metadata/_custom_type_script = "uid://1ejbvr3431ac"
+36 -5
View File
@@ -1,8 +1,39 @@
@abstract
extends Resource
class_name Scene
@export var scene_id : String
@export_file_path() var scene_path : String
@export var mouse_captured := false
@export var need_terrain_generated := false
@export var need_to_be_saved = true
const DEFAULT_SCENE_ICON = preload("res://common/icons/globe.svg")
var scene_id : String : get = get_scene_id
var scene_path : String : get = get_scene_path
var mouse_captured : bool : get = is_mouse_captured
var need_terrain_generated :bool : get = is_terrain_generated
var need_to_be_saved : bool : get = is_needed_to_be_saved
var need_to_announce : bool : get = is_needed_to_be_announced
var icon : Texture : get = get_scene_icon
func get_scene_id() -> String:
return ""
@abstract func get_scene_path() -> String
func is_mouse_captured() -> bool:
return false
func is_terrain_generated() -> bool:
return false
func is_needed_to_be_saved() -> bool:
return true
func is_needed_to_be_announced() -> bool:
return false
func get_scene_title() -> String:
return tr(get_scene_id())
func get_scene_icon() -> Texture:
return DEFAULT_SCENE_ICON
func _on_generated(_generated_scene : Node):
pass
+12 -21
View File
@@ -1,7 +1,5 @@
extends Node
@export var scenes : Array[Scene]
signal scene_loaded(scene : Scene)
signal scene_node_ready(scene : Scene)
@@ -11,25 +9,8 @@ var generating_node = false
var next_scene_node : Node
@onready var current_scene_node : Node = get_tree().root.get_children().back()
func search_scenes(scene_id : String) -> Scene:
var scene_pos : int = scenes.find_custom(
func (s : Scene):
return s.scene_id == scene_id
)
if scene_pos == -1:
return null
else :
return scenes[scene_pos]
func change_to_scene_id(scene_id : String, with_loading = true):
var scene = search_scenes(scene_id)
if not scene:
printerr("Scene %s not found" % scene_id)
return
if not loading_scene:
change_to_scene(scene, with_loading)
func _ready():
%SceneAnnounce.hide()
func change_to_scene(scene : Scene, with_loading = true):
if loading_scene or generating_node:
@@ -94,6 +75,16 @@ func _process(_delta):
if next_scene_node.is_generated:
generating_node = false
scene_node_ready.emit()
announce_scene(actual_scene)
actual_scene._on_generated(next_scene_node)
elif next_scene_node.is_node_ready():
generating_node = false
scene_node_ready.emit(actual_scene)
announce_scene(actual_scene)
actual_scene._on_generated(next_scene_node)
func announce_scene(scene : Scene):
if scene.need_to_announce:
%SceneTitle.text = scene.get_scene_title()
%SceneIcon.texture = scene.get_scene_icon()
%SceneAnnounceAnimationPlayer.play("announce")
@@ -0,0 +1,20 @@
extends Scene
class_name AstraScene
func get_scene_id() -> String:
return "ASTRA"
func get_scene_path() -> String:
return "res://stages/3d_scenes/astra_base/astra_base.tscn"
func is_mouse_captured() -> bool:
return true
func is_needed_to_be_announced() -> bool:
return true
func get_scene_title() -> String:
return tr("ASTRA_FACTORY")
func get_scene_icon() -> Texture:
return preload("res://common/icons/building-factory-2.svg")
@@ -0,0 +1 @@
uid://gyo84wyg8cy0
@@ -0,0 +1,11 @@
extends Scene
class_name BoreaScene
func get_scene_id() -> String:
return "BOREA_BASE"
func get_scene_path() -> String:
return "res://stages/3d_scenes/borea_base/borea_base.tscn"
func is_mouse_captured() -> bool:
return true
@@ -0,0 +1 @@
uid://0lbebb57m1vb
@@ -0,0 +1,20 @@
extends Scene
class_name CockpitScene
func get_scene_id() -> String:
return "COCKPIT"
func get_scene_path() -> String:
return "res://stages/3d_scenes/cockpit_scene/cockpit_scene.tscn"
func is_mouse_captured() -> bool:
return true
func is_needed_to_be_announced() -> bool:
return true
func get_scene_title() -> String:
return tr("INTERNODE")
func get_scene_icon() -> Texture:
return preload("res://common/icons/rocket.svg")
@@ -0,0 +1 @@
uid://8topyewe3juk
@@ -0,0 +1,20 @@
extends Scene
class_name GarageScene
func get_scene_id() -> String:
return "GARAGE"
func get_scene_path() -> String:
return "res://stages/3d_scenes/ship_garage/ship_garage.tscn"
func is_mouse_captured() -> bool:
return true
func is_needed_to_be_announced() -> bool:
return true
func get_scene_title() -> String:
return tr("ASTRA_SHIP_GARAGE")
func get_scene_icon() -> Texture:
return preload("res://common/icons/rocket.svg")
@@ -0,0 +1 @@
uid://3m1wltyvx0hp
@@ -0,0 +1,8 @@
extends Scene
class_name IntroScene
func get_scene_id() -> String:
return "INTRO"
func get_scene_path() -> String:
return "res://stages/intro/intro.tscn"
@@ -0,0 +1 @@
uid://ca755sowjsqtp
@@ -0,0 +1,30 @@
extends Scene
class_name RegionScene
@export var region_data : RegionData
func _init(
_rd : RegionData = null
):
region_data = _rd
func get_scene_id() -> String:
return "REGION"
func get_scene_path() -> String:
return "res://stages/terrain/region/region.tscn"
func is_terrain_generated() -> bool:
return true
func is_needed_to_be_announced() -> bool:
return true
func get_scene_title() -> String:
if region_data:
return region_data.region_name
return ""
func _on_generated(generated_scene : Node):
var region : Region = generated_scene as Region
region.finish_generation()
@@ -0,0 +1 @@
uid://degjtx6n43ta4
@@ -0,0 +1,91 @@
extends Scene
class_name RelayBaseScene
@export var base_name : String
@export var base_number : String
@export var is_spawning : bool
const DEAD_ORCHID_SCENE = preload("res://entities/player_3d/dead_orchid.tscn")
func _init(
_base_name : String = "",
_base_number : String = "",
_is_spawning : bool = false,
):
base_name = _base_name
base_number = _base_number
is_spawning = _is_spawning
func get_scene_path() -> String:
return "res://stages/3d_scenes/relay_base/relay_base.tscn"
func get_scene_title() -> String:
return tr("RELAY_BASE_X") % tr(base_name)
func get_scene_icon() -> Texture:
return preload("res://common/icons/route.svg")
func is_mouse_captured() -> bool:
return true
func is_needed_to_be_announced() -> bool:
return true
func _on_generated(generated_scene : Node):
var relay_base := generated_scene as RelayBase
relay_base.base_name = base_name
relay_base.base_number = base_number
if is_spawning:
AudioManager.play_sfx("Respawn")
spawn_player(relay_base)
spawn_dead_orchid(relay_base)
relay_base.exit_scene = CockpitScene.new()
else:
relay_base.exit_scene = RegionScene.new(GameInfo.game_data.current_region_data)
handle_orchid_save(relay_base)
func spawn_player(relay_base : RelayBase):
var incubators := relay_base.get_incubators()
var possible_incubators : Array[Incubator] = []
var choosen_incubator : Incubator = null
for i in range(len(incubators)):
var incubator = incubators[i]
if i in GameInfo.game_data.incubator_used:
incubator.used = true
else:
possible_incubators.append(incubator)
if len(possible_incubators):
choosen_incubator = possible_incubators.pick_random()
GameInfo.game_data.incubator_used.append(
incubators.find(choosen_incubator)
)
else:
choosen_incubator = incubators.pick_random()
choosen_incubator.used = true
relay_base.player.global_position = choosen_incubator.global_position + Vector3.UP
relay_base.player.rotation.y = choosen_incubator.rotation.y
func spawn_dead_orchid(relay_base : RelayBase):
var dead_orchid := DEAD_ORCHID_SCENE.instantiate() as Node3D
relay_base.add_child(dead_orchid)
if GameInfo.game_data.dead_orchid_position == Vector3.ZERO:
dead_orchid.global_position = relay_base.orchid_saver.global_position + Vector3.UP * 0.5
dead_orchid.rotation.y = -90
else:
dead_orchid.position = GameInfo.game_data.dead_orchid_position
dead_orchid.rotation = GameInfo.game_data.dead_orchid_rotation
relay_base.orchid_saver.active = false
relay_base.dead_orchid = dead_orchid
func handle_orchid_save(relay_base : RelayBase):
relay_base.orchid_saved.connect(
func ():
GameInfo.game_data.finish_story_step()
var new_story_step = GameInfo.game_data.progression_data.get_story_step()
SceneManager.change_to_scene(
new_story_step.get_respawn_scene()
)
)
@@ -0,0 +1 @@
uid://cnpm8ciojdjxf
@@ -0,0 +1,11 @@
extends Scene
class_name TitleScene
func get_scene_id() -> String:
return "TITTLE"
func get_scene_path() -> String:
return "res://stages/title_screen/title_screen.tscn"
func is_needed_to_be_saved() -> bool:
return false
@@ -0,0 +1 @@
uid://dn1psyrjkcynd
@@ -0,0 +1,31 @@
extends Scene
class_name VendingMachineScene
@export var vending_machine_room_seed = 0
func _init(
_vmrs : int = 0
):
vending_machine_room_seed = _vmrs
func get_scene_id() -> String:
return "VENDING_MACHINE"
func get_scene_path() -> String:
return "res://stages/3d_scenes/vending_machine_room/vending_machine_room.tscn"
func is_mouse_captured() -> bool:
return true
func is_needed_to_be_announced() -> bool:
return true
func get_scene_title() -> String:
return tr("VENDING_MACHINE_ROOM")
func get_scene_icon() -> Texture:
return preload("res://common/icons/building-store.svg")
func _on_generated(generated_scene : Node):
var vending_machine_room : VendingMachineRoom = generated_scene as VendingMachineRoom
vending_machine_room.setup_room(vending_machine_room_seed)
@@ -0,0 +1 @@
uid://b8gdowt2oavcy