Initial commit

This commit is contained in:
krampus 2024-07-20 18:36:11 +00:00
commit 6d52f9cc88
14 changed files with 471 additions and 0 deletions

49
.gdlintrc Normal file
View File

@ -0,0 +1,49 @@
class-definitions-order:
- tools
- classnames
- extends
- docstrings
- signals
- enums
- consts
- exports
- pubvars
- prvvars
- onreadypubvars
- onreadyprvvars
- staticvars
- others
class-load-variable-name: (([A-Z][a-z0-9]*)+|_?[a-z][a-z0-9]*(_[a-z0-9]+)*)
class-name: ([A-Z][a-z0-9]*)+
class-variable-name: _?[a-z][a-z0-9]*(_[a-z0-9]+)*
comparison-with-itself: null
constant-name: _?[A-Z][A-Z0-9]*(_[A-Z0-9]+)*
disable: []
duplicated-load: null
enum-element-name: '[A-Z][A-Z0-9]*(_[A-Z0-9]+)*'
enum-name: ([A-Z][a-z0-9]*)+
excluded_directories: !!set
.git: null
addons: null
expression-not-assigned: null
function-argument-name: _?[a-z][a-z0-9]*(_[a-z0-9]+)*
function-arguments-number: 10
function-name: (_on_([A-Z][a-z0-9]*)+(_[a-z0-9]+)*|_?[a-z][a-z0-9]*(_[a-z0-9]+)*)
function-preload-variable-name: ([A-Z][a-z0-9]*)+
function-variable-name: '[a-z][a-z0-9]*(_[a-z0-9]+)*'
load-constant-name: (([A-Z][a-z0-9]*)+|_?[A-Z][A-Z0-9]*(_[A-Z0-9]+)*)
loop-variable-name: _?[a-z][a-z0-9]*(_[a-z0-9]+)*
max-file-lines: 1000
max-line-length: 100
max-public-methods: 20
max-returns: 6
mixed-tabs-and-spaces: null
no-elif-return: null
no-else-return: null
private-method-call: null
signal-name: '[a-z][a-z0-9]*(_[a-z0-9]+)*'
sub-class-name: _?([A-Z][a-z0-9]*)+
tab-characters: 1
trailing-whitespace: null
unnecessary-pass: null
unused-argument: null

4
.gitattributes vendored Normal file
View File

@ -0,0 +1,4 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf
*.svg filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text

31
.githooks/pre-commit Executable file
View File

@ -0,0 +1,31 @@
#!/bin/sh
GDFORMAT=gdformat
GDLINT=gdlint
VENV=.venv
PYTHON=python3
PIP=$VENV/bin/pip
if ! which $GDFORMAT &> /dev/null; then
if ! test -f $VENV/bin/$GDFORMAT; then
if ! which $PYTHON &> /dev/null; then
echo "Please install Python 3"
exit 1
fi
echo "gdscript-toolkit will be installed locally under $VENV."
echo "this only needs to be performed once."
echo "creating venv..."
$PYTHON -m venv $VENV
echo "installing gdscript-toolkit..."
$PIP install -r requirements.txt
fi
GDFORMAT=$VENV/bin/$GDFORMAT
GDLINT=$VENV/bin/$GDLINT
fi
set -x
$GDFORMAT --check .
$GDLINT .

21
.gitignore vendored Normal file
View File

@ -0,0 +1,21 @@
# Godot 4+ specific ignores
.godot/
# Godot-specific ignores
.import/
export.cfg
export_presets.cfg
# Imported translations (automatically generated from CSV files)
*.translation
# Mono-specific ignores
.mono/
data_*/
mono_crash.*.json
# Python venv
.venv
# Project demos
/demos/

160
DEVELOPMENT.md Normal file
View File

@ -0,0 +1,160 @@
# DEVELOPMENT.md
This is a set of general guidelines for developers.
## Dev Tools
This project uses `gdlint` and `gdformat` from
[Scony/godot-gdscript-toolkit](https://github.com/Scony/godot-gdscript-toolkit)
for linting & formatting, respectively.
These tools are integrated into our development workflow using Godot
plugins:
[ryan-haskell/gdformat-on-save](https://github.com/ryan-haskell/gdformat-on-save)
and
[krampus/gdlint-plugin](https://git.of.the.spectacle.lol/krampus/gdlint-plugin)
respectively.
When a script is saved in the Godot editor, it is automatically
formatted and checked for linting errors which are shown as warnings.
### Setup on Linux Environment
`gdlint` and `gdformat` require Python >=3.8. On Ubuntu:
```bash
$ sudo apt update
$ sudo apt install python3 python3-venv
```
Next, install `gdscript-toolkit` through `pip`:
```bash
$ pip install --user -r requirements.txt
```
Then run `godot`. The plugins should be configured automatically.
(If you prefer to install `gdscript-toolkit` in a venv, just make sure
the plugins can find their required binaries.)
### Setup on Windows Environment
Download and run the appropriate installer from the [Python website](https://www.python.org/downloads/windows/)
During installation, select the "Add python.exe to PATH" checkbox when prompted.
Open "Windows PowerShell" and run the following command to make sure pip is installed:
```
pip --version
```
Assuming pip is installed you should see a message like:
```
pip 24.0 from C:\Users\dummy\AppData\Local\Programs\Python\Python312\Lib\site-packages\pip (python 3.12)
```
If pip is installed, run the following command to install the toolkit for the linter and formatter:
```
install gdtoolkit==4.2.2
```
Then run the following command to finish the installation process:
```
pip install setuptools==69.5.1
```
Check that everything installed by running "gdlint -h" and you should see something like:
```
GDScript linter
A tool for diagnosing typical GDScript code problems.
On success and the exitcode is 0.
On failure, python exception or list of problems is shown and exitcode is non-zero.
...
```
Also run "gdformat -h" and you should see something like:
```
GDScript formatter
Uncompromising GDScript code formatter. The only configurable thing is
max line length allowed and tabs/spaces indent. The rest will be taken
care of by gdformat in a one, consistent way.
...
```
### Git Hooks
If you like, you can use the included githooks to automatically check formatting & linting before making a commit.
You can enable our githooks like this:
```bash
$ git config core.hooksPath .githooks
```
## Standards & Practices
### Style
Code should generally conform to the [GDScript style
guide](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_styleguide.html)
where possible. Use the provided [linter and formatter](#dev-tools) to
apply most style guidelines automatically.
### Type Annotations
Use explicit type annotations wherever possible. Don't fret about it
too much, this is GDScript and there are a lot of situations where you
gotta do some freaky duck typing, but try to do as much explicit type
annotation as you can.
### Organization
_NOTE update this section as we build out the project more_
- All non-code assets go under `assets`
- Graphical assets go under `assets/images`
- Sprites go under `assets/images/sprites`
- Audio assets go under `assets/audio`
- Music goes under `assets/audio/music`
- SFX assets go under `assets/audio/sfx`
- Video assets go under `assets/video`
- Scenes and GDScript source files go under `src`
- Godot plugins go under `addons`
## Git Workflow
We use a standard branching workflow. Here's the full process of getting something merged in:
1. [Create an issue](../../../issues/new) for the feature you want to
implement or the bug you want to fix, and assign it to
yourself. Alternately, pick an existing issue you want to work on
from the [issue tracker](../../../issues).
2. In your local repo, create a new branch off of `main`. Your feature
branch's name should include the issue number and a brief
descriptive title, e.g. `37-immanentize-eschaton` or similar.
3. Build the feature or fix the bug or whatever it is you're
doing. Frequent, small commits are preferred, and it's a good idea
to merge new changes from `main` often.
4. Push your changes to the server and
[create a pull request](../../../compare/main...main) to merge your
feature branch into `main`. Your PR description should include the
changes you made. If you include the phrase _"closes #[issue
number]"_ in your PR description, the issue will automatically be
closed when your PR is merged, which is nice.
5. Request review from `intrusive/Owners`. If your patch touches
something you think a specific dev needs to see, tag them for
review explicitly.
6. Once your PR gets approval from either 1 member of
`intrusive/Owners` or from the specific developer who needs to see
it, merge it into `main` yourself. There should be a button on the
PR page to do this. If it says you can't merge automatically, you
probably need to merge new changes from `main`
7. If it wasn't done automatically, close the issue and delete the
feature branch.
Try to stick to the above workflow as much as you can, but occasional
shortcuts for hotfixes etc aren't the end of the world.

7
README.md Normal file
View File

@ -0,0 +1,7 @@
# Sunstation
Stylish mech combat game (prototype)
## Development
see [[DEVELOPMENT.md]]

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Ryan Haskell-Glatz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,70 @@
@tool
class_name FormatOnSave extends EditorPlugin
const SUCCESS: int = 0
const AUTO_RELOAD_SETTING: String = "text_editor/behavior/files/auto_reload_scripts_on_external_change"
var original_auto_reload_setting: bool
# LIFECYCLE EVENTS
func _enter_tree():
activate_auto_reload_setting()
resource_saved.connect(on_resource_saved)
func _exit_tree():
resource_saved.disconnect(on_resource_saved)
restore_original_auto_reload_setting()
# CALLED WHEN A SCRIPT IS SAVED
func on_resource_saved(resource: Resource):
if resource is Script:
var script: Script = resource
var current_script = get_editor_interface().get_script_editor().get_current_script()
var text_edit: CodeEdit = (
get_editor_interface().get_script_editor().get_current_editor().get_base_editor()
)
# Prevents other unsaved scripts from overwriting the active one
if current_script == script:
var filepath: String = ProjectSettings.globalize_path(resource.resource_path)
# Run gdformat
var exit_code = OS.execute("gdformat", [filepath])
# Replace source_code with formatted source_code
if exit_code == SUCCESS:
var formatted_source = FileAccess.get_file_as_string(resource.resource_path)
FormatOnSave.reload_script(text_edit, formatted_source)
# Workaround until this PR is merged:
# https://github.com/godotengine/godot/pull/83267
# Thanks, @KANAjetzt 💖
static func reload_script(text_edit: TextEdit, source_code: String) -> void:
var column := text_edit.get_caret_column()
var row := text_edit.get_caret_line()
var scroll_position_h := text_edit.get_h_scroll_bar().value
var scroll_position_v := text_edit.get_v_scroll_bar().value
text_edit.text = source_code
text_edit.set_caret_column(column)
text_edit.set_caret_line(row)
text_edit.scroll_horizontal = scroll_position_h
text_edit.scroll_vertical = scroll_position_v
text_edit.tag_saved_version()
# For this workaround to work, we need to disable the "Reload/Resave" pop-up
func activate_auto_reload_setting():
var settings := get_editor_interface().get_editor_settings()
original_auto_reload_setting = settings.get(AUTO_RELOAD_SETTING)
settings.set(AUTO_RELOAD_SETTING, true)
# If the plugin is disabled, let's attempt to restore the original editor setting
func restore_original_auto_reload_setting():
var settings := get_editor_interface().get_editor_settings()
settings.set(AUTO_RELOAD_SETTING, original_auto_reload_setting)

View File

@ -0,0 +1,6 @@
[plugin]
name="Format on Save"
description="Runs `gdformat` on save to automatically format your GD script as you code."
author="Ryan Haskell-Glatz"
version="1.2.0"
script="format_on_save.gd"

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Rob Kelly <contact@robkel.ly>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,6 @@
[plugin]
name="gdLint Plugin"
description="Static code analysis with `gdlint`"
author="Rob Kelly"
version="1.0.0"
script="run_linter.gd"

View File

@ -0,0 +1,33 @@
@tool
class_name GDLintPlugin extends EditorPlugin
# If you've installed gdlint in a venv, you may want to overwrite this
const GDLINT: String = "gdlint"
func _enter_tree() -> void:
assert(not OS.execute(GDLINT, ["-h"]), "Could not find gdLint binary at {0}".format([GDLINT]))
resource_saved.connect(on_save)
func _exit_tree() -> void:
resource_saved.disconnect(on_save)
func on_save(resource: Resource) -> void:
# Run linting when a script resource is saved
if resource is Script:
var script: Script = resource
var filepath: String = ProjectSettings.globalize_path(resource.resource_path)
var script_editor = EditorInterface.get_script_editor()
var code_editor: CodeEdit = (
script_editor.get_current_editor().get_base_editor()
if script_editor.get_current_script() == script
else null
)
var gdlint_output: Array[String] = []
var error: int = OS.execute(GDLINT, [filepath], gdlint_output, true)
if error:
push_warning("gdLint:\n" + gdlint_output[0])

40
project.godot Normal file
View File

@ -0,0 +1,40 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="Sunstation"
config/features=PackedStringArray("4.2", "Forward Plus")
run/max_fps=60
config/icon="res://icon.svg"
[debug]
gdscript/warnings/untyped_declaration=2
gdscript/warnings/unsafe_property_access=2
gdscript/warnings/unsafe_method_access=2
gdscript/warnings/unsafe_cast=1
gdscript/warnings/unsafe_call_argument=2
[display]
window/stretch/mode="canvas_items"
[dotnet]
project/assembly_name="Sunstation"
[editor]
movie_writer/movie_file="demos/demo.avi"
[editor_plugins]
enabled=PackedStringArray("res://addons/format_on_save/plugin.cfg", "res://addons/gdlint_plugin/plugin.cfg")

2
requirements.txt Normal file
View File

@ -0,0 +1,2 @@
gdtoolkit>=4.2.2,<4.3
setuptools>=69.5.1,<69.6