Browse Source

[WIP] Split up lobby -> menu, lobby, custom_game

lobby.gd had gotten big, bloated, ugly, and hard to read. It needed a
refactor. The first thing I did is split up the *GUI* into the logical
steps it should be. So the new flow is:

 - Start the game
 - Click "Quick Play"
 - Matchmaking begins on my dedicated server

 - Start the game
 - Click "Custom Game"
 - *Only now* am I presented with server / client options

 - Start the game
 - Click "Singleplayer"
 - Singleplayer

NOW, and only now, and NO MATTER WHAT PATH I TAKE, I am taken to the
*lobby*, which now is where I:
 - Choose my name
 - Choose hero
 - See list of players
 - Get my team assigned
 - Anything else that I might like to put in
The point here is that this has *nothing* to do with handshaking /
matchmaking / etc! This is just part of the game! At this point I have
*already been connected* to the server. I've already been aquainted with
my other players. The game has begun.

I put the things that don't belong in any of these flows in
networking.gd, a sort of model-view sorta thing. All of these flows use
some sort of networking thing like `init_server` that tbh should be
*completely* abstracted from the UI.

It's totally a WIP!!! Above is the IDEA, but below is what I've actually
*done*:
 - Made the scenes, made a passable UI for each one that at least
 indicates ~what they'll do
 - Made the corresponding scripts, and split up the lobby script into
 ABOUT where I think it'll end up, but no promises
It still errors all over the place, and it's nowhere near properly
organized. PLUS, I'd also like to rewrite a lot of the code / rename
things as part of the initial refactor goal of making me able to
actually think about networking.
master
Luna 7 years ago
parent
commit
6bb81381d4
12 changed files with 739 additions and 763 deletions
  1. +16
    -0
      assets/theme.tres
  2. +2
    -0
      plans.md
  3. +5
    -1
      project.godot
  4. +235
    -0
      scenes/custom_game.tscn
  5. +80
    -529
      scenes/lobby.tscn
  6. +142
    -0
      scenes/menu.tscn
  7. +9
    -0
      scripts/custom_game.gd
  8. +1
    -232
      scripts/lobby.gd
  9. +0
    -1
      scripts/matchmaking.gd
  10. +83
    -0
      scripts/menu.gd
  11. +164
    -0
      scripts/networking.gd
  12. +2
    -0
      scripts/util.gd

+ 16
- 0
assets/theme.tres View File

@ -0,0 +1,16 @@
[gd_resource type="Theme" load_steps=3 format=2]
[ext_resource path="res://assets/DejaVuSansMono.ttf" type="DynamicFontData" id=1]
[sub_resource type="DynamicFont" id=1]
size = 18
use_mipmaps = false
use_filter = false
font_data = ExtResource( 1 )
_sections_unfolded = [ "Font", "Settings" ]
[resource]
default_font = SubResource( 1 )

+ 2
- 0
plans.md View File

@ -26,6 +26,8 @@ Smaller TODOs:
- Ira is OP?
- Nerfed - 5 walls
- Make motion more reactive?
- Remember some player settings, probably in a player.json or something
- I'm mostly thinking of nickname, but also SR eventually
Bugs:


+ 5
- 1
project.godot View File

@ -11,13 +11,17 @@ config_version=3
[application]
config/name="nv-moba"
run/main_scene="res://scenes/lobby.tscn"
run/main_scene="res://scenes/menu.tscn"
config/icon="res://icon.png"
[autoload]
util="*res://scripts/util.gd"
[display]
window/stretch/mode="viewport"
[input]
move_forwards=[ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":44,"unicode":0,"echo":false,"script":null)


+ 235
- 0
scenes/custom_game.tscn View File

@ -0,0 +1,235 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://assets/theme.tres" type="Theme" id=1]
[ext_resource path="res://scripts/custom_game.gd" type="Script" id=2]
[ext_resource path="res://assets/DejaVuSansMono.ttf" type="DynamicFontData" id=3]
[sub_resource type="DynamicFont" id=1]
size = 30
use_mipmaps = false
use_filter = false
font_data = ExtResource( 3 )
[node name="CustomGame" type="Control"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 40.0
margin_bottom = 40.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
theme = ExtResource( 1 )
script = ExtResource( 2 )
[node name="VSeparator" type="VSeparator" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 498.0
margin_top = 140.0
margin_right = 518.0
margin_bottom = 563.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
[node name="Label" type="Label" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 54.0
margin_top = 66.0
margin_right = 395.0
margin_bottom = 102.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
custom_fonts/font = SubResource( 1 )
text = "Custom Game"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Server" type="Button" parent="." index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 68.0
margin_top = 261.0
margin_right = 272.0
margin_bottom = 331.0
rect_pivot_offset = Vector2( 0, 0 )
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
text = "Host Game"
flat = false
align = 1
[node name="LevelSelect" type="OptionButton" parent="." index="3"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 72.0
margin_top = 201.0
margin_right = 243.0
margin_bottom = 236.0
rect_pivot_offset = Vector2( 0, 0 )
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
action_mode = 0
enabled_focus_mode = 2
shortcut = null
group = null
text = "Platform map"
flat = false
align = 0
selected = 0
items = [ "Platform map", null, false, 0, null, "City-like thing", null, false, 1, null, "Slide", null, false, 2, null ]
[node name="Client" type="Button" parent="." index="4"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 588.0
margin_top = 258.0
margin_right = 812.0
margin_bottom = 332.0
rect_pivot_offset = Vector2( 0, 0 )
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
text = "Join Game"
flat = false
align = 1
[node name="IPLabel" type="Label" parent="." index="5"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 592.0
margin_top = 205.0
margin_right = 625.0
margin_bottom = 227.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "IP:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="IP" type="TextEdit" parent="." index="6"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 632.0
margin_top = 202.0
margin_right = 783.0
margin_bottom = 231.0
rect_pivot_offset = Vector2( 0, 0 )
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
text = "127.0.0.1"
readonly = false
highlight_current_line = false
syntax_highlighting = false
show_line_numbers = false
highlight_all_occurrences = false
override_selected_font_color = false
context_menu_enabled = true
smooth_scrolling = false
v_scroll_speed = 80.0
hiding_enabled = 0
wrap_lines = false
caret_block_mode = false
caret_blink = false
caret_blink_speed = 0.65
caret_moving_by_right_click = true
[node name="Label2" type="Label" parent="." index="7"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 72.0
margin_top = 145.0
margin_right = 171.0
margin_bottom = 167.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "Host game"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Label3" type="Label" parent="." index="8"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 577.0
margin_top = 147.0
margin_right = 617.0
margin_bottom = 169.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "Join Game"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1

+ 80
- 529
scenes/lobby.tscn View File

@ -1,18 +1,16 @@
[gd_scene load_steps=7 format=2]
[gd_scene load_steps=8 format=2]
[ext_resource path="res://scripts/lobby.gd" type="Script" id=1]
[ext_resource path="res://scripts/hero_select.gd" type="Script" id=2]
[ext_resource path="res://assets/theme.tres" type="Theme" id=1]
[ext_resource path="res://scripts/lobby.gd" type="Script" id=2]
[ext_resource path="res://scenes/hero_select.tscn" type="PackedScene" id=3]
[ext_resource path="res://assets/DejaVuSansMono.ttf" type="DynamicFontData" id=4]
[sub_resource type="DynamicFontData" id=1]
font_path = "res://assets/DejaVuSansMono.ttf"
[sub_resource type="DynamicFont" id=2]
[sub_resource type="DynamicFont" id=5]
size = 30
use_mipmaps = false
use_filter = false
font_data = SubResource( 1 )
font_data = ExtResource( 4 )
[sub_resource type="DynamicFontData" id=3]
@ -31,45 +29,6 @@ anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 80.0
margin_top = 99.0
margin_right = 120.0
margin_bottom = 139.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
script = ExtResource( 1 )
[node name="Title" type="Label" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 7.0
margin_top = -72.0
margin_right = 195.0
margin_bottom = -32.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
custom_fonts/font = SubResource( 2 )
text = "VANAGLORIA"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="GameBrowser" type="Control" parent="." index="1"]
editor/display_folded = true
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 40.0
margin_bottom = 40.0
rect_pivot_offset = Vector2( 0, 0 )
@ -77,158 +36,68 @@ mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
theme = ExtResource( 1 )
script = ExtResource( 2 )
[node name="Play" type="Button" parent="GameBrowser" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 9.0
margin_top = -2.0
margin_right = 405.0
margin_bottom = 53.0
rect_pivot_offset = Vector2( 0, 0 )
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
text = "Just, Play!"
flat = false
align = 1
[node name="PickAGameLabel" type="Label" parent="GameBrowser" index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 10.0
margin_top = 65.0
margin_right = 114.0
margin_bottom = 79.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "Or, pick a game:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="HeroSelect" parent="." index="0" instance=ExtResource( 3 )]
[node name="GameList" type="ItemList" parent="GameBrowser" index="2"]
editor/display_folded = true
margin_left = 28.0
margin_top = 98.0
margin_right = 28.0
margin_bottom = 98.0
color = Color( 0.097229, 0.104696, 0.105469, 0 )
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 8.0
margin_top = 87.0
margin_right = 411.0
margin_bottom = 208.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = true
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
items = [ "No Games Running", null, false ]
select_mode = 0
icon_mode = 1
fixed_icon_size = Vector2( 0, 0 )
[node name="Hero" parent="HeroSelect" index="0"]
[node name="Join" type="Button" parent="GameBrowser" index="3"]
margin_left = -2.0
margin_top = 41.0
margin_right = 370.0
margin_bottom = 108.0
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 9.0
margin_top = 217.0
margin_right = 163.0
margin_bottom = 244.0
rect_pivot_offset = Vector2( 0, 0 )
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
text = "Join Selected Game"
flat = false
align = 1
[node name="Confirm" parent="HeroSelect" index="1"]
[node name="VSeparator" type="VSeparator" parent="." index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 431.0
margin_top = -3.0
margin_right = 436.0
margin_bottom = 234.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
visible = false
[node name="PlayerSettings" type="Control" parent="." index="3"]
[node name="HeroDescription" parent="HeroSelect" index="2"]
editor/display_folded = true
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 40.0
margin_bottom = 40.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
margin_left = -2.0
margin_top = 133.0
margin_right = 366.0
margin_bottom = 250.0
text = "L Let s put oeuntahoeu nthaoeu ntaoheunt aoheunt hoaenth oaentuh Let s put oeuntahoeu nthaoeu ntaoheunt aoheunt hoaenth "
[node name="PlayerSettingsLabel" type="Label" parent="PlayerSettings" index="0"]
[node name="Title" type="Label" parent="HeroSelect" index="3"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 459.0
margin_top = -6.0
margin_right = 564.0
margin_bottom = 13.0
margin_left = 6.0
margin_top = 9.0
margin_right = 294.0
margin_bottom = 45.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "Player Settings"
custom_fonts/font = SubResource( 5 )
text = "Select your hero"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Username" type="TextEdit" parent="PlayerSettings" index="1"]
[node name="Username" type="TextEdit" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 457.0
margin_top = 27.0
margin_right = 636.0
margin_bottom = 47.0
margin_left = 42.0
margin_top = 423.0
margin_right = 383.0
margin_bottom = 456.0
rect_pivot_offset = Vector2( 0, 0 )
focus_mode = 2
mouse_filter = 0
@ -252,330 +121,92 @@ caret_blink = false
caret_blink_speed = 0.65
caret_moving_by_right_click = true
[node name="HeroSelectLabel" type="Label" parent="PlayerSettings" index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 460.0
margin_top = 66.0
margin_right = 538.0
margin_bottom = 80.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "Hero Select:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="HeroSelect" type="OptionButton" parent="PlayerSettings" index="3"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 457.0
margin_top = 94.0
margin_right = 645.0
margin_bottom = 114.0
rect_rotation = -0.0115615
rect_pivot_offset = Vector2( 0, 0 )
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
action_mode = 0
enabled_focus_mode = 2
shortcut = null
group = null
flat = false
align = 0
selected = -1
items = [ ]
script = ExtResource( 2 )
[node name="TeamLabel" type="Label" parent="PlayerSettings" index="4"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 459.0
margin_top = 132.0
margin_right = 558.0
margin_bottom = 146.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "Assigned team:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Team" type="Label" parent="PlayerSettings" index="5"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 460.0
margin_top = 157.0
margin_right = 500.0
margin_bottom = 171.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="HeroDescriptionLabel" type="Label" parent="PlayerSettings" index="6"]
[node name="TeamLabel" type="Label" parent="." index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 677.0
margin_top = -5.0
margin_right = 790.0
margin_bottom = 9.0
margin_left = 498.0
margin_top = 87.0
margin_right = 666.0
margin_bottom = 111.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "Hero Description:"
text = "Your team:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="HeroDescription" type="RichTextLabel" parent="PlayerSettings" index="7"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 675.0
margin_top = 15.0
margin_right = 918.0
margin_bottom = 245.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = true
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
bbcode_enabled = false
bbcode_text = ""
visible_characters = -1
percent_visible = 1.0
meta_underlined = true
tab_size = 4
text = ""
scroll_active = true
scroll_following = false
selection_enabled = false
override_selected_font_color = false
[node name="HSeparator3" type="HSeparator" parent="." index="4"]
[node name="Team" type="Label" parent="." index="3"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 19.0
margin_top = 271.0
margin_right = 645.0
margin_bottom = 275.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
[node name="CustomGame" type="Control" parent="." index="5"]
editor/display_folded = true
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 40.0
margin_bottom = 40.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
[node name="Label" type="Label" parent="CustomGame" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 671.0
margin_top = 275.0
margin_right = 874.0
margin_bottom = 289.0
margin_left = 625.0
margin_top = 87.0
margin_right = 665.0
margin_bottom = 111.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "Or, host or join a custom game:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Server" type="Button" parent="CustomGame" index="1"]
[node name="Players" type="Control" parent="." index="4"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 665.0
margin_top = 300.0
margin_right = 752.0
margin_bottom = 335.0
margin_left = 494.0
margin_top = 128.0
margin_right = 534.0
margin_bottom = 168.0
rect_pivot_offset = Vector2( 0, 0 )
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
text = "Server"
flat = false
align = 1
[node name="LevelSelect" type="OptionButton" parent="CustomGame" index="2"]
[node name="PlayerList" type="Label" parent="Players" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 770.0
margin_top = 300.0
margin_right = 895.0
margin_bottom = 335.0
rect_pivot_offset = Vector2( 0, 0 )
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
action_mode = 0
enabled_focus_mode = 2
shortcut = null
group = null
text = "Platform map"
flat = false
align = 0
selected = 0
items = [ "Platform map", null, false, 0, null, "City-like thing", null, false, 1, null, "Slide", null, false, 2, null ]
[node name="Client" type="Button" parent="CustomGame" index="3"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 667.0
margin_top = 354.0
margin_right = 753.0
margin_bottom = 393.0
rect_pivot_offset = Vector2( 0, 0 )
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
text = "Client"
flat = false
align = 1
[node name="IPLabel" type="Label" parent="CustomGame" index="4"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 673.0
margin_top = 403.0
margin_right = 698.0
margin_bottom = 419.0
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -14.0
margin_top = 2.0
margin_right = 487.0
margin_bottom = 280.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "IP:"
custom_fonts/font = SubResource( 4 )
text = "Waiting for players to connect...."
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="IP" type="TextEdit" parent="CustomGame" index="5"]
[node name="StartGame" type="Button" parent="Players" index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 707.0
margin_top = 401.0
margin_right = 851.0
margin_bottom = 419.0
rect_pivot_offset = Vector2( 0, 0 )
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
text = "127.0.0.1"
readonly = false
highlight_current_line = false
syntax_highlighting = false
show_line_numbers = false
highlight_all_occurrences = false
override_selected_font_color = false
context_menu_enabled = true
smooth_scrolling = false
v_scroll_speed = 80.0
hiding_enabled = 0
wrap_lines = false
caret_block_mode = false
caret_blink = false
caret_blink_speed = 0.65
caret_moving_by_right_click = true
[node name="Singleplayer" type="Button" parent="CustomGame" index="6"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 668.0
margin_top = 431.0
margin_right = 760.0
margin_bottom = 470.0
margin_left = 2.0
margin_top = 325.0
margin_right = 124.0
margin_bottom = 365.0
rect_pivot_offset = Vector2( 0, 0 )
focus_mode = 2
mouse_filter = 0
@ -586,105 +217,25 @@ toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
text = "Singleplayer"
text = "Ready!"
flat = false
align = 1
[node name="VSeparator2" type="VSeparator" parent="." index="6"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 653.0
margin_top = 273.0
margin_right = 657.0
margin_bottom = 467.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
[node name="JoinedGameLobby" type="Control" parent="." index="7"]
editor/display_folded = true
visible = false
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 40.0
margin_bottom = 40.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
[node name="PlayerListLabel" type="Label" parent="JoinedGameLobby" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 14.0
margin_top = 287.0
margin_right = 136.0
margin_bottom = 301.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "Connected Players:"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="PlayerList" type="Label" parent="JoinedGameLobby" index="1"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -7.0
margin_top = 287.0
margin_right = 639.0
margin_bottom = 433.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
custom_fonts/font = SubResource( 4 )
text = "Waiting for players to connect...."
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="StartGame" type="Button" parent="JoinedGameLobby" index="2"]
[node name="VSeparator" type="VSeparator" parent="." index="5"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 13.0
margin_top = 443.0
margin_right = 135.0
margin_bottom = 483.0
margin_left = 453.0
margin_top = 50.0
margin_right = 471.0
margin_bottom = 538.0
rect_pivot_offset = Vector2( 0, 0 )
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
text = "Start game"
flat = false
align = 1
[editable path="HeroSelect"]

+ 142
- 0
scenes/menu.tscn View File

@ -0,0 +1,142 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://assets/theme.tres" type="Theme" id=1]
[ext_resource path="res://scripts/menu.gd" type="Script" id=2]
[sub_resource type="DynamicFontData" id=1]
font_path = "res://assets/DejaVuSansMono.ttf"
[sub_resource type="DynamicFont" id=2]
size = 30
use_mipmaps = false
use_filter = false
font_data = SubResource( 1 )
[node name="Menu" type="Control"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 1024.0
margin_bottom = 600.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
theme = ExtResource( 1 )
script = ExtResource( 2 )
[node name="Title" type="Label" parent="." index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 60.0
margin_top = 50.0
margin_right = 248.0
margin_bottom = 90.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
custom_fonts/font = SubResource( 2 )
text = "VANAGLORIA"
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
[node name="Center" type="Control" parent="." index="1"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -20.0
margin_top = -20.0
margin_right = 20.0
margin_bottom = 20.0
rect_pivot_offset = Vector2( 0, 0 )
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
[node name="Play" type="Button" parent="Center" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = -250.0
margin_top = -70.0
margin_right = 298.0
margin_bottom = -10.0
rect_pivot_offset = Vector2( 0, 0 )
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
text = "Quick Play"
flat = false
align = 1
[node name="CustomGame" type="Button" parent="Center" index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = -252.0
margin_top = 14.0
margin_right = 300.0
margin_bottom = 75.0
rect_pivot_offset = Vector2( 0, 0 )
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
text = "Custom Game"
flat = false
align = 1
[node name="Singleplayer" type="Button" parent="Center" index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = -251.0
margin_top = 104.0
margin_right = 299.0
margin_bottom = 170.0
rect_pivot_offset = Vector2( 0, 0 )
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
text = "Singleplayer"
flat = false
align = 1

+ 9
- 0
scripts/custom_game.gd View File

@ -0,0 +1,9 @@
extends Control
onready var networking = preload("res://scripts/networking.gd").new()
func _ready():
add_child(networking)
get_node("Server").connect("pressed", networking, server_init)
get_node("Client").connect("pressed", networking, client_init)

+ 1
- 232
scripts/lobby.gd View File

@ -1,8 +1,5 @@
extends "res://scripts/args.gd"
extends Control
# class member variables go here, for example:
# var a = 2
# var b = "textvar"
var port = null # Defined by command-line argument with default
var player_info = {}
@ -18,40 +15,10 @@ onready var matchmaking = preload("res://scripts/matchmaking.gd").new()
var matchmaker_tcp
func setup_options():
var opts = Options.new()
opts.set_banner(('A non-violent MOBA inspired by Overwatch and Zineth'))
opts.add('-singleplayer', false, 'Whether to run singeplayer, starting immediately')
opts.add('-server', false, 'Whether to run as server')
opts.add('-matchmaker', false, 'Whether to be the sole matchmaker')
opts.add('-client', false, 'Immediately connect as client')
opts.add('-silent', false, 'If the server is not playing, merely serving')
opts.add('-port', 54672, 'The port to run a server on or connect to')
opts.add('-hero', 'r', 'Your choice of hero (index)')
opts.add('-level', 'r', 'Your choice of level (index) - server only!')
opts.add('-start-game', false, 'Join as a client and immediately start the game')
opts.add('-ai', true, 'Run this client as AI')
opts.add('-no-record', true, "Don't record this play for AI later")
opts.add('-h', false, "Print help")
return opts
func option_sel(button_name, option):
var button = get_node(button_name)
if option == "r":
option = randi() % button.get_item_count()
else:
option = int(option)
button.select(option)
func _ready():
add_child(matchmaking)
my_info.version = [0,0,0] # Semantic versioning: [0].[1].[2]
randomize()
parse_args()
get_node("GameBrowser/Play").connect("pressed", self, "connect_global_server")
get_node("PlayerSettings/HeroSelect").connect("item_selected", self, "select_hero")
get_node("PlayerSettings/Username").connect("text_changed", self, "resend_name")
@ -65,104 +32,6 @@ func _ready():
get_tree().connect("network_peer_disconnected", self, "_player_disconnected")
get_tree().connect("connected_to_server", self, "_connected_ok")
func parse_args():
var o = setup_options()
o.parse()
if o.get_value("-silent"):
server_playing = false # TODO: Uncaps :(
if o.get_value("-hero"):
var hero = o.get_value("-hero")
option_sel("PlayerSettings/HeroSelect", hero)
# For some reason, calling option_sel doesn't trigger the actual selection
select_hero(get_node("PlayerSettings/HeroSelect").get_selected_id())
if o.get_value("-level"):
option_sel("CustomGame/LevelSelect", o.get_value("-level"))
if o.get_value("-server"):
call_deferred("_server_init")
if o.get_value("-matchmaker"):
call_deferred("_matchmaker_init")
if o.get_value("-client"):
call_deferred("_client_init")
if o.get_value("-port"):
port = o.get_value("-port")
if o.get_value("-start-game"):
my_info.start_game = true
if o.get_value("-singleplayer"):
call_deferred("_singleplayer_init")
if o.get_value("-ai"):
my_info.is_ai = true
if not o.get_value("-no-record") and not o.get_value("-ai"):
my_info.record = true
if o.get_value('-h'):
o.print_help()
quit()
func connect_global_server():
ip = global_server_ip
_client_init()
slave func _client_init(given_port=null):
collect_info()
var peer = NetworkedMultiplayerENet.new()
if not ip:
ip = get_node("CustomGame/IP").get_text()
ip = IP.resolve_hostname(ip)
if given_port:
port = given_port
print("Connecting to " + ip + ":" + str(port))
peer.create_client(ip, port)
get_tree().set_network_peer(peer)
get_node("CustomGame/Client").set_text("Clienting!")
func _singleplayer_init():
collect_info()
var peer = NetworkedMultiplayerENet.new()
peer.create_server(port, 1)
get_tree().set_network_peer(peer)
player_info[1] = my_info
start_game()
func _server_init():
collect_info()
var peer = NetworkedMultiplayerENet.new()
print("Starting server on port " + str(port))
peer.create_server(port, matchmaking.GAME_SIZE)
get_tree().set_network_peer(peer)
# As soon as we're listening, let the matchmaker know
var matchmaker_peer = StreamPeerTCP.new()
matchmaker_peer.connect_to_host("127.0.0.1", matchmaking.SERVER_TO_SERVER_PORT)
matchmaker_tcp = PacketPeerStream.new()
matchmaker_tcp.set_stream_peer(matchmaker_peer)
# matchmaker_tcp.put_packet([matchmaking.messages.ready_to_connect, port])
matchmaker_tcp.put_var(matchmaking.messages.ready_to_connect)
matchmaker_tcp.put_var(port)
is_connected = true
get_node("CustomGame/Server").set_text("Serving!")
get_node("JoinedGameLobby").show()
if server_playing:
player_info[1] = my_info
if "start_game" in my_info and my_info.start_game:
start_game()
func _matchmaker_init():
matchmaking.run_matchmaker()
func _player_connected(id):
pass
func _player_disconnected(id):
if get_tree().is_network_server():
rpc("unregister_player", id)
call_deferred("render_player_list")
func _connected_ok():
rpc("register_player", get_tree().get_network_unique_id(), my_info)
if "start_game" in my_info and my_info.start_game:
rpc_id(1, "start_game")
get_node("JoinedGameLobby").show()
is_connected = true
func collect_info():
if not "username" in my_info:
my_info.username = get_node("PlayerSettings/Username").get_text()
@ -171,43 +40,6 @@ func collect_info():
if not "is_right_team" in my_info:
my_info.is_right_team = false # Server assigns team, wait for that
remote func register_player(new_peer, info):
player_info[new_peer] = info
render_player_list()
if (get_tree().is_network_server()):
var right_team_count = 0
# Send current players' info to new player
for old_peer in player_info:
# Send new player, old player's info
rpc_id(new_peer, "register_player", old_peer, player_info[old_peer])
if old_peer != new_peer:
# We need to assign team later, so count current
if player_info[old_peer].is_right_team:
right_team_count += 1
# You'd think this part could be met with a simple `rpc(`, but actually it can't
# My best guess is this is because we haven't registered the names yet, but I'm not sure (TODO)
if old_peer != 1:
# Send old player, new player's info (not us, no infinite loop)
rpc_id(old_peer, "register_player", new_peer, info)
if begun:
rpc_id(old_peer, "spawn_player", new_peer)
rpc_id(old_peer, "begin_player_deferred", new_peer) # Spawning is deferred
if not server_playing:
# We didn't catch this in player_info
rpc_id(1, "spawn_player", new_peer)
rpc_id(1, "begin_player_deferred", new_peer) # Spawning is deferred
var assign_right_team = right_team_count * 2 < player_info.size()
rpc("assign_team", new_peer, assign_right_team)
if not begun and player_info.size() == matchmaking.GAME_SIZE:
start_game()
if begun:
rpc_id(new_peer, "pre_configure_game", my_info.level)
rpc_id(new_peer, "post_configure_game")
sync func unregister_player(peer):
player_info.erase(peer)
get_node("/root/Level/Players/%d" % peer).queue_free()
func select_hero(hero):
var description = get_node("PlayerSettings/HeroSelect").hero_text[hero]
get_node("PlayerSettings/HeroDescription").set_text(description)
@ -227,15 +59,6 @@ sync func set_name(peer, name):
player_info[peer].username = name
render_player_list()
sync func assign_team(peer, is_right_team):
player_info[peer].is_right_team = is_right_team
if peer == get_tree().get_network_unique_id():
if is_right_team:
get_node("PlayerSettings/Team").set_text("Right Team")
else:
get_node("PlayerSettings/Team").set_text("Left Team")
render_player_list()
func render_player_list():
if has_node("PlayerSettings"):
var list = ""
@ -250,57 +73,3 @@ func render_player_list():
list += "\n"
get_node("JoinedGameLobby/PlayerList").set_text(list)
sync func start_game():
my_info.level = get_node("CustomGame/LevelSelect").get_selected_id()
rpc("pre_configure_game", my_info.level)
sync func done_preconfiguring(who):
players_done.append(who)
if players_done.size() == player_info.size():
# We call deferred in case singleplayer has placing the player in queue still
call_deferred("rpc", "post_configure_game")
sync func spawn_player(p):
var hero = player_info[p].hero
var player = load("res://scenes/heroes/" + str(hero) + ".tscn").instance()
player.set_name(str(p))
player.set_network_master(p)
player.player_info = player_info[p]
get_node("/root/Level/Players").call_deferred("add_child", player)
sync func pre_configure_game(level):
begun = true
my_info.level = level # Remember the level for future player registration
var self_peer_id = get_tree().get_network_unique_id()
# Remove the interface so as to not fuck with things
# But we still need the lobby alive to deal with networking!
for element in get_node("/root/Lobby").get_children():
element.queue_free()
var world = load("res://scenes/levels/%d.tscn" % level).instance()
get_node("/root").add_child(world)
# Load all players (including self)
for p in player_info:
player_info[p].level = level
spawn_player(p)
rpc_id(1, "done_preconfiguring", self_peer_id)
func begin_player(peer):
get_node("/root/Level/Players/%d" % peer).begin()
remote func begin_player_deferred(peer):
call_deferred("begin_player", peer)
sync func reset_state():
players_done = []
get_node("/root/Level").queue_free()
sync func post_configure_game():
# Begin all players (including self)
for p in player_info:
begin_player_deferred(p)

+ 0
- 1
scripts/matchmaking.gd View File

@ -83,7 +83,6 @@ func add_to_game(netid, port):
lobby.rpc_id(netid, "_client_init", port)
func skirmish_to_game(port, count=1):
print("dropping 'em in")
for i in range(count):
if not skirmishing_players.size():
return false


+ 83
- 0
scripts/menu.gd View File

@ -0,0 +1,83 @@
extends "res://scripts/args.gd"
func _ready():
randomize()
_parse_args()
_gui_setup()
# GUI
func _gui_setup():
get_node("Center/Play").connect("pressed", self, "_find_game")
get_node("Center/CustomGame").connect("pressed", self, "_custom_game")
get_node("Center/Singleplayer").connect("pressed", self, "_singleplayer")
func _find_game():
print("still refactoring matchmaker")
func _custom_game():
get_tree().change_scene("res://scenes/custom_game.tscn")
func _singleplayer():
print("still refactoring singleplayer")
# Command line
func _set_up_options():
var opts = Options.new()
opts.set_banner(('A non-violent MOBA inspired by Overwatch and Zineth'))
opts.add('-singleplayer', false, 'Whether to run singeplayer, starting immediately')
opts.add('-server', false, 'Whether to run as server')
opts.add('-matchmaker', false, 'Whether to be the sole matchmaker')
opts.add('-client', false, 'Immediately connect as client')
opts.add('-silent', false, 'If the server is not playing, merely serving')
opts.add('-port', 54672, 'The port to run a server on or connect to')
opts.add('-hero', 'r', 'Your choice of hero (index)')
opts.add('-level', 'r', 'Your choice of level (index) - server only!')
opts.add('-start-game', false, 'Join as a client and immediately start the game')
opts.add('-ai', true, 'Run this client as AI')
opts.add('-no-record', true, "Don't record this play for AI later")
opts.add('-h', false, "Print help")
return opts
func _option_sel(button_name, option):
var button = get_node(button_name)
if option == "r":
option = randi() % button.get_item_count()
else:
option = int(option)
button.select(option)
func _parse_args():
var o = setup_options()
o.parse()
# if o.get_value("-silent"):
# server_playing = false
# if o.get_value("-hero"):
# var hero = o.get_value("-hero")
# _option_sel("PlayerSettings/HeroSelect", hero)
# # For some reason, calling _option_sel doesn't trigger the actual selection
# select_hero(get_node("PlayerSettings/HeroSelect").get_selected_id())
# if o.get_value("-level"):
# _option_sel("CustomGame/LevelSelect", o.get_value("-level"))
# if o.get_value("-server"):
# call_deferred("_server_init")
# if o.get_value("-matchmaker"):
# call_deferred("_matchmaker_init")
# if o.get_value("-client"):
# call_deferred("_client_init")
# if o.get_value("-port"):
# port = o.get_value("-port")
# if o.get_value("-start-game"):
# my_info.start_game = true
# if o.get_value("-singleplayer"):
# call_deferred("_singleplayer_init")
# if o.get_value("-ai"):
# my_info.is_ai = true
# if not o.get_value("-no-record") and not o.get_value("-ai"):
# my_info.record = true
# if o.get_value('-h'):
# o.print_help()
# quit()

+ 164
- 0
scripts/networking.gd View File

@ -0,0 +1,164 @@
extends Node
func connect_global_server():
ip = global_server_ip
_client_init()
slave func client_init(given_port=null):
collect_info()
var peer = NetworkedMultiplayerENet.new()
if not ip:
ip = get_node("CustomGame/IP").get_text()
ip = IP.resolve_hostname(ip)
if given_port:
port = given_port
print("Connecting to " + ip + ":" + str(port))
peer.create_client(ip, port)
get_tree().set_network_peer(peer)
get_node("CustomGame/Client").set_text("Clienting!")
func singleplayer_init():
collect_info()
var peer = NetworkedMultiplayerENet.new()
peer.create_server(port, 1)
get_tree().set_network_peer(peer)
player_info[1] = my_info
start_game()
func server_init():
collect_info()
var peer = NetworkedMultiplayerENet.new()
print("Starting server on port " + str(port))
peer.create_server(port, matchmaking.GAME_SIZE)
get_tree().set_network_peer(peer)
# As soon as we're listening, let the matchmaker know
var matchmaker_peer = StreamPeerTCP.new()
matchmaker_peer.connect_to_host("127.0.0.1", matchmaking.SERVER_TO_SERVER_PORT)
matchmaker_tcp = PacketPeerStream.new()
matchmaker_tcp.set_stream_peer(matchmaker_peer)
# matchmaker_tcp.put_packet([matchmaking.messages.ready_to_connect, port])
matchmaker_tcp.put_var(matchmaking.messages.ready_to_connect)
matchmaker_tcp.put_var(port)
is_connected = true
get_node("CustomGame/Server").set_text("Serving!")
get_node("JoinedGameLobby").show()
if server_playing:
player_info[1] = my_info
if "start_game" in my_info and my_info.start_game:
start_game()
func matchmaker_init():
matchmaking.run_matchmaker()
func player_disconnected(id):
if get_tree().is_network_server():
rpc("unregister_player", id)
call_deferred("render_player_list")
func player_connected():
rpc("register_player", get_tree().get_network_unique_id(), my_info)
if "start_game" in my_info and my_info.start_game:
rpc_id(1, "start_game")
get_node("JoinedGameLobby").show()
is_connected = true
remote func register_player(new_peer, info):
player_info[new_peer] = info
render_player_list()
if (get_tree().is_network_server()):
var right_team_count = 0
# Send current players' info to new player
for old_peer in player_info:
# Send new player, old player's info
rpc_id(new_peer, "register_player", old_peer, player_info[old_peer])
if old_peer != new_peer:
# We need to assign team later, so count current
if player_info[old_peer].is_right_team:
right_team_count += 1
# You'd think this part could be met with a simple `rpc(`, but actually it can't
# My best guess is this is because we haven't registered the names yet, but I'm not sure (TODO)
if old_peer != 1:
# Send old player, new player's info (not us, no infinite loop)
rpc_id(old_peer, "register_player", new_peer, info)
if begun:
rpc_id(old_peer, "spawn_player", new_peer)
rpc_id(old_peer, "begin_player_deferred", new_peer) # Spawning is deferred
if not server_playing:
# We didn't catch this in player_info
rpc_id(1, "spawn_player", new_peer)
rpc_id(1, "begin_player_deferred", new_peer) # Spawning is deferred
var assign_right_team = right_team_count * 2 < player_info.size()
rpc("assign_team", new_peer, assign_right_team)
if not begun and player_info.size() == matchmaking.GAME_SIZE:
start_game()
if begun:
rpc_id(new_peer, "pre_configure_game", my_info.level)
rpc_id(new_peer, "post_configure_game")
sync func unregister_player(peer):
player_info.erase(peer)
get_node("/root/Level/Players/%d" % peer).queue_free()
sync func assign_team(peer, is_right_team):
player_info[peer].is_right_team = is_right_team
if peer == get_tree().get_network_unique_id():
if is_right_team:
get_node("PlayerSettings/Team").set_text("Right Team")
else:
get_node("PlayerSettings/Team").set_text("Left Team")
render_player_list()
sync func start_game():
my_info.level = get_node("CustomGame/LevelSelect").get_selected_id()
rpc("pre_configure_game", my_info.level)
sync func done_preconfiguring(who):
players_done.append(who)
if players_done.size() == player_info.size():
# We call deferred in case singleplayer has placing the player in queue still
call_deferred("rpc", "post_configure_game")
sync func spawn_player(p):
var hero = player_info[p].hero
var player = load("res://scenes/heroes/" + str(hero) + ".tscn").instance()
player.set_name(str(p))
player.set_network_master(p)
player.player_info = player_info[p]
get_node("/root/Level/Players").call_deferred("add_child", player)
sync func pre_configure_game(level):
begun = true
my_info.level = level # Remember the level for future player registration
var self_peer_id = get_tree().get_network_unique_id()
# Remove the interface so as to not fuck with things
# But we still need the lobby alive to deal with networking!
for element in get_node("/root/Lobby").get_children():
element.queue_free()
var world = load("res://scenes/levels/%d.tscn" % level).instance()
get_node("/root").add_child(world)
# Load all players (including self)
for p in player_info:
player_info[p].level = level
spawn_player(p)
rpc_id(1, "done_preconfiguring", self_peer_id)
func begin_player(peer):
get_node("/root/Level/Players/%d" % peer).begin()
remote func begin_player_deferred(peer):
call_deferred("begin_player", peer)
sync func reset_state():
players_done = []
get_node("/root/Level").queue_free()
sync func post_configure_game():
# Begin all players (including self)
for p in player_info:
begin_player_deferred(p)

+ 2
- 0
scripts/util.gd View File

@ -1,5 +1,7 @@
extends Node
var version = [0,0,0] # Semantic versioning: [0].[1].[2]
func get_master_player():
var path = "/root/Level/Players/%d" % get_tree().get_network_unique_id()
if has_node(path):


Loading…
Cancel
Save