mirror of
https://github.com/godotengine/godot-docs.git
synced 2025-12-31 17:49:03 +03:00
ReadTheDocs redirect automation.
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,3 +1,7 @@
|
||||
*.csv
|
||||
!redirects.csv
|
||||
.env
|
||||
|
||||
_build/
|
||||
env/
|
||||
__pycache__
|
||||
|
||||
47
_tools/redirects/README.md
Normal file
47
_tools/redirects/README.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# ReadTheDocs redirect tools
|
||||
|
||||
The scripts located in this directory help in creating and maintaining redirects on [Read the Docs](https://readthedocs.io).
|
||||
Also refer to Read the Docs [API documentation](https://docs.readthedocs.io/en/stable/api/index.html).
|
||||
|
||||
Note that RTD redirects only apply in case of 404 errors, and to all branches and languages:
|
||||
<https://docs.readthedocs.io/en/stable/user-defined-redirects.html>.
|
||||
If this ever changes, we need to rework how we manage these (likely adding per-branch logic).
|
||||
|
||||
`convert_git_renames_to_csv.py` creates a list of renamed files in Git to create redirects for.
|
||||
`create_redirects.py` is used to actually manage redirects on ReadTheDocs.
|
||||
|
||||
For more information on the scripts themselves, see their help output.
|
||||
|
||||
## Setup
|
||||
|
||||
To install requirements: `pip3 install -r requirements.txt`.
|
||||
Git is also required and needs to be available in the `PATH`.
|
||||
To interact with the Read the Docs API, a valid API key must be set as
|
||||
`RTD_AUTH_TOKEN` (either as a environment variable or in a [.env file](https://pypi.org/project/python-dotenv/)).
|
||||
|
||||
## Usage
|
||||
|
||||
Lets say we recently renamed some files in the Git branch `3.4` (compared to the `stable` branch), and now we want to create redirects for these.
|
||||
For this, we would (after setting up the API token and requirements, see Setup above):
|
||||
|
||||
> python convert_git_renames_to_csv.py stable 3.4
|
||||
|
||||
This should output a list of the redirects to create. Lets append these to the redirects file:
|
||||
|
||||
> python convert_git_renames_to_csv.py stable 3.4 >> redirects.csv
|
||||
|
||||
After this, redirects for renamed files should have been appended to `redirects.csv`. You may want to double check that!
|
||||
Now lets submit these to ReadTheDocs and create redirects there:
|
||||
|
||||
> python create_redirects.py
|
||||
|
||||
And that should be it!
|
||||
|
||||
The script takes care to not add duplicate redirects if the same ones already exist.
|
||||
The created redirects are also valid for all branches and languages, which works out
|
||||
as they only apply for actually missing files - when a user encounters a 404, that is.
|
||||
|
||||
The script also only touches `page` type redirects, all other types may still be added
|
||||
and managed manually on RTD or via other means. All `page` redirects need to
|
||||
be managed with these tools however, as they will otherwise just overwrite any
|
||||
changes made elsewhere.
|
||||
@@ -1,4 +1,6 @@
|
||||
"""Uses git to list files that were renamed between two revisions and converts
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""Uses Git to list files that were renamed between two revisions and converts
|
||||
that to a CSV table.
|
||||
|
||||
Use it to prepare and double-check data for create_redirects.py.
|
||||
@@ -9,32 +11,40 @@ import argparse
|
||||
import csv
|
||||
import sys
|
||||
|
||||
try:
|
||||
subprocess.check_output(["git", "--version"])
|
||||
except subprocess.CalledProcessError:
|
||||
print("Git not found. It's required to run this program.")
|
||||
|
||||
|
||||
def parse_command_line_args():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Uses git to list files that were renamed between two revisions and "
|
||||
description="Uses Git to list files that were renamed between two revisions and "
|
||||
"converts that to a CSV table. Use it to prepare and double-check data for create_redirects.py."
|
||||
)
|
||||
parser.add_argument(
|
||||
"revision1",
|
||||
type=str,
|
||||
help="Start revision to get renamed files from.",
|
||||
help="Start revision to get renamed files from (old).",
|
||||
)
|
||||
parser.add_argument(
|
||||
"revision2",
|
||||
type=str,
|
||||
help="End revision to get renamed files from.",
|
||||
help="End revision to get renamed files from (new).",
|
||||
)
|
||||
parser.add_argument("-f", "--output-file", type=str, help="Path to the output file")
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def dict_item_to_str(item):
|
||||
s = ""
|
||||
for key in item:
|
||||
s += item[key]
|
||||
return s
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
subprocess.check_output(["git", "--version"])
|
||||
except subprocess.CalledProcessError:
|
||||
print("Git not found. It's required to run this program.")
|
||||
exit(1)
|
||||
|
||||
args = parse_command_line_args()
|
||||
assert args.revision1 != args.revision2, "Revisions must be different."
|
||||
for revision in [args.revision1, args.revision2]:
|
||||
@@ -49,7 +59,7 @@ def main():
|
||||
except subprocess.CalledProcessError:
|
||||
print(
|
||||
f"Revision {revision} not found in this repository. "
|
||||
"Please make sure that both revisions exist locally in your git repository."
|
||||
"Please make sure that both revisions exist locally in your Git repository."
|
||||
)
|
||||
exit(1)
|
||||
|
||||
@@ -68,25 +78,34 @@ def main():
|
||||
.decode("utf-8")
|
||||
.split("\n")
|
||||
)
|
||||
renamed_documents = [f for f in renamed_files if f.endswith(".rst")]
|
||||
renamed_documents = [f for f in renamed_files if f.lower().endswith(".rst")]
|
||||
|
||||
csv_data: list[dict] = []
|
||||
branch = args.revision2
|
||||
|
||||
for document in renamed_documents:
|
||||
_, source, destination = document.split("\t")
|
||||
source = source.replace(".rst", ".html")
|
||||
destination = destination.replace(".rst", ".html")
|
||||
if not source.startswith("/"):
|
||||
source = "/" + source
|
||||
if not destination.startswith("/"):
|
||||
destination = "/" + destination
|
||||
csv_data.append(
|
||||
{"source": source, "destination": destination, "branch": branch}
|
||||
{"source": source, "destination": destination}
|
||||
)
|
||||
|
||||
if args.output_file:
|
||||
with open(args.output_file, "w") as f:
|
||||
writer = csv.DictWriter(f, fieldnames=csv_data[0].keys()).writerows(
|
||||
csv_data
|
||||
)
|
||||
writer.writeheader()
|
||||
writer.writerows(csv_data)
|
||||
else:
|
||||
writer = csv.DictWriter(sys.stdout, fieldnames=csv_data[0].keys())
|
||||
if len(csv_data) < 1:
|
||||
print("No renames found for", args.revision1, "->", args.revision2)
|
||||
return
|
||||
|
||||
csv_data.sort(key=dict_item_to_str)
|
||||
|
||||
out = args.output_file
|
||||
if not out:
|
||||
out = sys.stdout.fileno()
|
||||
|
||||
with open(out, "w", encoding="utf-8", newline="") as f:
|
||||
writer = csv.DictWriter(f, fieldnames=csv_data[0].keys())
|
||||
writer.writeheader()
|
||||
writer.writerows(csv_data)
|
||||
|
||||
|
||||
@@ -1,111 +1,324 @@
|
||||
"""Create page redirects for a specific branch of the docs.
|
||||
#!/usr/bin/env python3
|
||||
|
||||
Loads data from a CSV file with three columns: source, destination, branch
|
||||
|
||||
Where the source and destination are paths to RST files in the repository.
|
||||
|
||||
Pre-requisites:
|
||||
|
||||
- You need the dotenv Python module installed. We use this to let you store your
|
||||
API auth token privately.
|
||||
|
||||
You can install it by running: pip3 install -r requirements.txt
|
||||
"""Manages page redirects for the Godot documentation on ReadTheDocs. (https://docs.godotengine.org)
|
||||
Note that RTD redirects only apply in case of 404 errors, and to all branches and languages:
|
||||
https://docs.readthedocs.io/en/stable/user-defined-redirects.html.
|
||||
If this ever changes, we need to rework how we manage these (likely adding per-branch logic).
|
||||
|
||||
How to use:
|
||||
- Install requirements: pip3 install -r requirements.txt
|
||||
- Store your API token in RTD_API_TOKEN environment variable or
|
||||
a .env file (the latter requires the package dotenv)
|
||||
- Generate new redirects from two git revisions using convert_git_renames_to_csv.py
|
||||
- Run this script
|
||||
|
||||
- Generate a CSV file from two git revisions using convert_git_renames_to_csv.py
|
||||
- Store your API token in a .env variable in this directory like so:
|
||||
RTD_API_TOKEN=your_token_here
|
||||
- Run this script, passing it the path to your generated CSV file as an
|
||||
argument.
|
||||
Example:
|
||||
python convert_git_renames_to_csv.py stable 3.4 >> redirects.csv
|
||||
python create_redirects.py
|
||||
|
||||
The script directly creates redirects using the CSV data. It does not check if a
|
||||
redirect already exist or if it's correct.
|
||||
This would add all files that were renamed in 3.4 from stable to redirects.csv,
|
||||
and then create the redirects on RTD accordingly.
|
||||
Care is taken to not add redirects that already exist on RTD.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import csv
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
|
||||
import dotenv
|
||||
import requests
|
||||
from requests.models import default_hooks
|
||||
from requests.adapters import HTTPAdapter
|
||||
from requests.packages.urllib3.util.retry import Retry
|
||||
|
||||
try:
|
||||
import requests
|
||||
except ImportError:
|
||||
print(
|
||||
"Required third-party module `requests` not found. "
|
||||
"Please install it with `pip install requests` (or `pip3 install requests` on Linux)."
|
||||
)
|
||||
|
||||
|
||||
dotenv.load_dotenv()
|
||||
RTD_AUTH_TOKEN: str = os.environ.get("RTD_AUTH_TOKEN", "")
|
||||
if RTD_AUTH_TOKEN == "":
|
||||
print("Missing auth token in .env file or .env file not found. Aborting.")
|
||||
exit(1)
|
||||
|
||||
REDIRECT_URL = "https://readthedocs.org/api/v3/projects/pip/redirects/"
|
||||
REQUEST_HEADERS = {"Authorization": f"token {RTD_AUTH_TOKEN}"}
|
||||
|
||||
RTD_AUTH_TOKEN = ""
|
||||
REQUEST_HEADERS = ""
|
||||
REDIRECT_URL = "https://readthedocs.org/api/v3/projects/godot/redirects/"
|
||||
USER_AGENT = "Godot RTD Redirects on Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"
|
||||
DEFAULT_PAGINATED_SIZE = 1024
|
||||
API_SLEEP_TIME = 0.2 # Seconds.
|
||||
REDIRECT_SUFFIXES = [".html", "/"]
|
||||
TIMEOUT_SECONDS = 5
|
||||
HTTP = None
|
||||
|
||||
def parse_command_line_args():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Create page redirects for a specific branch of the docs."
|
||||
)
|
||||
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
parser.add_argument(
|
||||
"csv_file",
|
||||
"-f",
|
||||
"--file",
|
||||
metavar="file",
|
||||
default="redirects.csv",
|
||||
type=str,
|
||||
help="Path to a CSV file with three columns: source, destination, branch.",
|
||||
help="Path to a CSV file used to keep a list of redirects, containing two columns: source and destination.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--delete",
|
||||
action="store_true",
|
||||
help="Deletes all currently setup 'page' and 'exact' redirects on ReadTheDocs.",
|
||||
)
|
||||
# add dry-run argument
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--dry-run",
|
||||
action="store_true",
|
||||
help="Run the program and output information without side effects.",
|
||||
help="Safe mode: Run the program and output information without any calls to the ReadTheDocs API.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--dump",
|
||||
action="store_true",
|
||||
help="Only dumps or deletes (if --delete) existing RTD redirects, skips submission.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"--verbose",
|
||||
action="store_true",
|
||||
help="Enables verbose output.",
|
||||
)
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def make_redirect(source, destination, branch, args):
|
||||
# Currently, the program only works for the EN version of the docs
|
||||
trimmed_source = source.replace(".rst", "")
|
||||
trimmed_destination = destination.replace(".rst", "")
|
||||
def make_redirect(source, destination, args, retry=0):
|
||||
json_data = {"from_url": source, "to_url": destination, "type": "page"}
|
||||
headers = REQUEST_HEADERS
|
||||
|
||||
if args.verbose:
|
||||
print("POST " + REDIRECT_URL, headers, json_data)
|
||||
|
||||
source_slug = f"/en/{branch}/{trimmed_source}"
|
||||
destination_slug = f"/en/{branch}/{trimmed_destination}"
|
||||
json_data = {"from_url": source_slug, "to_url": destination_slug, "type": "page"}
|
||||
if args.dry_run:
|
||||
print(f"{source_slug} -> {destination_slug}")
|
||||
print(f"Created redirect {source} -> {destination} (DRY RUN)")
|
||||
return
|
||||
|
||||
response = HTTP.post(
|
||||
REDIRECT_URL,
|
||||
json=json_data,
|
||||
headers=headers,
|
||||
timeout=TIMEOUT_SECONDS
|
||||
)
|
||||
|
||||
if response.status_code == 201:
|
||||
print(f"Created redirect {source} -> {destination}")
|
||||
elif response.status_code == 429 and retry<5:
|
||||
retry += 1
|
||||
time.sleep(retry*retry)
|
||||
make_redirect(source, destination, args, retry)
|
||||
return
|
||||
else:
|
||||
response = requests.post(
|
||||
REDIRECT_URL,
|
||||
json=json.dumps(json_data),
|
||||
headers=REQUEST_HEADERS,
|
||||
print(
|
||||
f"Failed to create redirect {source} -> {destination}. "
|
||||
f"Status code: {response.status_code}"
|
||||
)
|
||||
if response.status_code == 201:
|
||||
print(f"Created redirect {source_slug} -> {destination_slug}")
|
||||
exit(1)
|
||||
|
||||
|
||||
def sleep():
|
||||
time.sleep(API_SLEEP_TIME)
|
||||
|
||||
|
||||
def id(from_url, to_url):
|
||||
return from_url + " -> " + to_url
|
||||
|
||||
|
||||
def get_paginated(url, parameters={"limit": DEFAULT_PAGINATED_SIZE}):
|
||||
entries = []
|
||||
count = -1
|
||||
while True:
|
||||
data = HTTP.get(
|
||||
url,
|
||||
headers=REQUEST_HEADERS,
|
||||
params=parameters,
|
||||
timeout=TIMEOUT_SECONDS
|
||||
)
|
||||
if data.status_code != 200:
|
||||
if data.status_code == 401:
|
||||
print("Access denied, check RTD API key in RTD_AUTH_TOKEN!")
|
||||
print("Error accessing RTD API: " + url + ": " + str(data.status_code))
|
||||
exit(1)
|
||||
else:
|
||||
json = data.json()
|
||||
if json["count"] and count < 0:
|
||||
count = json["count"]
|
||||
entries.extend(json["results"])
|
||||
next = json["next"]
|
||||
if next and len(next) > 0 and next != url:
|
||||
url = next
|
||||
sleep()
|
||||
continue
|
||||
if count > 0 and len(entries) != count:
|
||||
print(
|
||||
f"Failed to create redirect {source_slug} -> {destination_slug}. "
|
||||
f"Status code: {response.status_code}"
|
||||
"Mismatch getting paginated content from " + url + ": " +
|
||||
"expected " + str(count) + " items, got " + str(len(entries)))
|
||||
exit(1)
|
||||
return entries
|
||||
|
||||
|
||||
def delete_redirect(id):
|
||||
url = REDIRECT_URL + str(id)
|
||||
data = HTTP.delete(url, headers=REQUEST_HEADERS, timeout=TIMEOUT_SECONDS)
|
||||
if data.status_code != 204:
|
||||
print("Error deleting redirect with ID", id, "- code:", data.status_code)
|
||||
exit(1)
|
||||
else:
|
||||
print("Deleted redirect", id, "on RTD.")
|
||||
|
||||
|
||||
def get_existing_redirects(delete=False):
|
||||
redirs = get_paginated(REDIRECT_URL)
|
||||
existing = []
|
||||
for redir in redirs:
|
||||
if redir["type"] != "page":
|
||||
print(
|
||||
"Ignoring redirect (only type 'page' is handled): #" +
|
||||
str(redir["pk"]) + " " + id(redir["from_url"], redir["to_url"]) +
|
||||
" on ReadTheDocs is '" + redir["type"] + "'. "
|
||||
)
|
||||
continue
|
||||
if delete:
|
||||
delete_redirect(redir["pk"])
|
||||
sleep()
|
||||
else:
|
||||
existing.append([redir["from_url"], redir["to_url"]])
|
||||
return existing
|
||||
|
||||
|
||||
def set_auth(token):
|
||||
global RTD_AUTH_TOKEN
|
||||
RTD_AUTH_TOKEN = token
|
||||
global REQUEST_HEADERS
|
||||
REQUEST_HEADERS = {"Authorization": f"token {RTD_AUTH_TOKEN}", "User-Agent": USER_AGENT}
|
||||
|
||||
|
||||
def load_auth():
|
||||
try:
|
||||
import dotenv
|
||||
dotenv.load_dotenv()
|
||||
except:
|
||||
print("Failed to load dotenv. If you want to use .env files, install the dotenv.")
|
||||
token = os.environ.get("RTD_AUTH_TOKEN", "")
|
||||
if len(token) < 1:
|
||||
print("Missing auth token in RTD_AUTH_TOKEN env var or .env file not found. Aborting.")
|
||||
exit(1)
|
||||
set_auth(token)
|
||||
|
||||
|
||||
def has_suffix(s, suffixes):
|
||||
for suffix in suffixes:
|
||||
if s.endswith(suffix):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def is_valid_redirect_url(url):
|
||||
if len(url) < len("/a"):
|
||||
return False
|
||||
|
||||
if not has_suffix(url.lower(), REDIRECT_SUFFIXES):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def redirect_to_str(item):
|
||||
return id(item[0], item[1])
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_command_line_args()
|
||||
redirect_data = []
|
||||
with open(args.csv_file, "r") as f:
|
||||
redirect_data = list(csv.DictReader(f))
|
||||
assert redirect_data[0].keys() == {
|
||||
"source",
|
||||
"destination",
|
||||
"branch",
|
||||
}, "CSV file must have those three columns: source, destination, branch."
|
||||
for row in redirect_data:
|
||||
make_redirect(row["source"], row["destination"], row["branch"], args)
|
||||
|
||||
if not args.dry_run:
|
||||
load_auth()
|
||||
|
||||
retry_strategy = Retry(
|
||||
total=3,
|
||||
status_forcelist=[429, 500, 502, 503, 504],
|
||||
backoff_factor=2,
|
||||
method_whitelist=["HEAD", "GET", "PUT", "DELETE", "OPTIONS", "TRACE"]
|
||||
)
|
||||
adapter = HTTPAdapter(max_retries=retry_strategy)
|
||||
global HTTP
|
||||
HTTP = requests.Session()
|
||||
HTTP.mount("https://", adapter)
|
||||
HTTP.mount("http://", adapter)
|
||||
|
||||
to_add = []
|
||||
redirects_file = []
|
||||
with open(args.file, "r", encoding="utf-8") as f:
|
||||
redirects_file = list(csv.DictReader(f))
|
||||
if len(redirects_file) > 0:
|
||||
assert redirects_file[0].keys() == {
|
||||
"source",
|
||||
"destination",
|
||||
}, "CSV file must have a header and two columns: source, destination."
|
||||
|
||||
for row in redirects_file:
|
||||
to_add.append([row["source"], row["destination"]])
|
||||
print("Loaded", len(redirects_file), "redirects from", args.file + ".")
|
||||
|
||||
existing = []
|
||||
if not args.dry_run:
|
||||
existing = get_existing_redirects(args.delete)
|
||||
print("Loaded", len(existing), "existing redirects from RTD.")
|
||||
|
||||
print("Total redirects:", str(len(to_add)) +
|
||||
" (+" + str(len(existing)), "existing.)")
|
||||
|
||||
redirects = []
|
||||
added = {}
|
||||
for redirect in to_add:
|
||||
if len(redirect) != 2:
|
||||
print("Invalid redirect:", redirect, "- expected 2 elements, got:", len(redirect))
|
||||
continue
|
||||
|
||||
if redirect[0] == redirect[1]:
|
||||
print("Invalid redirect:", redirect, "- redirects to itself!")
|
||||
continue
|
||||
|
||||
if not is_valid_redirect_url(redirect[0]) or not is_valid_redirect_url(redirect[1]):
|
||||
print("Invalid redirect:", redirect, "- invalid URL!")
|
||||
continue
|
||||
|
||||
if not redirect[0].startswith("/") or not redirect[1].startswith("/"):
|
||||
print("Invalid redirect:", redirect, "- invalid URL: should start with slash!")
|
||||
continue
|
||||
|
||||
redirect_id = id(redirect[0], redirect[1])
|
||||
if redirect_id in added:
|
||||
# Duplicate; skip.
|
||||
continue
|
||||
|
||||
reverse_id = id(redirect[1], redirect[0])
|
||||
if reverse_id in added:
|
||||
# Duplicate; skip.
|
||||
continue
|
||||
|
||||
added[redirect_id] = True
|
||||
redirects.append(redirect)
|
||||
|
||||
redirects.sort(key=redirect_to_str)
|
||||
|
||||
with open(args.file, "w", encoding="utf-8", newline="") as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerows([["source", "destination"]])
|
||||
writer.writerows(redirects)
|
||||
|
||||
existing_ids = {}
|
||||
for e in existing:
|
||||
existing_ids[id(e[0], e[1])] = True
|
||||
|
||||
if not args.dump:
|
||||
print("Creating redirects.")
|
||||
for redirect in redirects:
|
||||
if not id(redirect[0], redirect[1]) in existing_ids:
|
||||
make_redirect(redirect[0], redirect[1], args)
|
||||
|
||||
if not id(redirect[1], redirect[0]) in existing_ids:
|
||||
make_redirect(redirect[1], redirect[0], args)
|
||||
|
||||
if not args.dry_run:
|
||||
sleep()
|
||||
|
||||
print("Finished creating", len(redirects), "redirects.")
|
||||
print("(" + str(2*len(redirects)) + " including reverse redirects.)")
|
||||
|
||||
if args.dry_run:
|
||||
print("THIS WAS A DRY RUN, NOTHING WAS SUBMITTED TO READTHEDOCS!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
390
_tools/redirects/redirects.csv
Normal file
390
_tools/redirects/redirects.csv
Normal file
@@ -0,0 +1,390 @@
|
||||
source,destination
|
||||
/classes/_classes.html,/classes/
|
||||
/classes/class_bulletphysicsserver.html,/classes/class_gltfdocument.html
|
||||
/community/tutorials/3d/mesh_generation_with_heightmap_and_shaders.html,/tutorials/3d/mesh_generation_with_heightmap_and_shaders.html
|
||||
/community/tutorials/gdnative/gdnative-c-example.html,/tutorials/plugins/gdnative/gdnative-c-example.html
|
||||
/community/tutorials/gdnative/index.html,/tutorials/plugins/gdnative/index.html
|
||||
/community/tutorials/vr/index.html,/tutorials/vr/index.html
|
||||
/community/tutorials/vr/vr_primer.html,/tutorials/vr/vr_primer.html
|
||||
/content/3d/making_trees.html,/tutorials/content/making_trees.html
|
||||
/contributing/_contributing.html,/community/contributing/
|
||||
/contributing/bug_triage_guidelines.html,/community/contributing/bug_triage_guidelines.html
|
||||
/contributing/doc_and_l10n_guidelines.html,/community/contributing/doc_and_l10n_guidelines.html
|
||||
/contributing/updating_the_class_reference.html,/community/contributing/updating_the_class_reference.html
|
||||
/development/consoles/consoles.html,/tutorials/platform/consoles.html
|
||||
/development/plugins/import_plugins.html,/tutorials/plugins/editor/import_plugins.html
|
||||
/development/plugins/index.html,/tutorials/plugins/editor/index.html
|
||||
/development/plugins/making_plugins.html,/tutorials/plugins/editor/making_plugins.html
|
||||
/getting_started/editor/command_line_tutorial.html,/tutorials/editor/command_line_tutorial.html
|
||||
/getting_started/editor/default_key_mapping.html,/tutorials/editor/default_key_mapping.html
|
||||
/getting_started/editor/external_editor.html,/tutorials/editor/external_editor.html
|
||||
/getting_started/editor/using_the_web_editor.html,/tutorials/editor/using_the_web_editor.html
|
||||
/getting_started/scripting/c_sharp/c_sharp_basics.html,/tutorials/scripting/c_sharp/c_sharp_basics.html
|
||||
/getting_started/scripting/c_sharp/c_sharp_differences.html,/tutorials/scripting/c_sharp/c_sharp_differences.html
|
||||
/getting_started/scripting/c_sharp/c_sharp_features.html,/tutorials/scripting/c_sharp/c_sharp_features.html
|
||||
/getting_started/scripting/c_sharp/c_sharp_style_guide.html,/tutorials/scripting/c_sharp/c_sharp_style_guide.html
|
||||
/getting_started/scripting/c_sharp/index.html,/tutorials/scripting/c_sharp/index.html
|
||||
/getting_started/scripting/creating_script_templates.html,/tutorials/scripting/creating_script_templates.html
|
||||
/getting_started/scripting/cross_language_scripting.html,/tutorials/scripting/cross_language_scripting.html
|
||||
/getting_started/scripting/gdscript/gdscript_advanced.html,/tutorials/scripting/gdscript/gdscript_advanced.html
|
||||
/getting_started/scripting/gdscript/gdscript_basics.html,/tutorials/scripting/gdscript/gdscript_basics.html
|
||||
/getting_started/scripting/gdscript/gdscript_exports.html,/tutorials/scripting/gdscript/gdscript_exports.html
|
||||
/getting_started/scripting/gdscript/gdscript_format_string.html,/tutorials/scripting/gdscript/gdscript_format_string.html
|
||||
/getting_started/scripting/gdscript/gdscript_styleguide.html,/tutorials/scripting/gdscript/gdscript_styleguide.html
|
||||
/getting_started/scripting/gdscript/index.html,/tutorials/scripting/gdscript/index.html
|
||||
/getting_started/scripting/gdscript/static_typing.html,/tutorials/scripting/gdscript/static_typing.html
|
||||
/getting_started/scripting/gdscript/warning_system.html,/tutorials/scripting/gdscript/warning_system.html
|
||||
/getting_started/scripting/visual_script/custom_visualscript_nodes.html,/tutorials/scripting/visual_script/custom_visualscript_nodes.html
|
||||
/getting_started/scripting/visual_script/getting_started.html,/tutorials/scripting/visual_script/getting_started.html
|
||||
/getting_started/scripting/visual_script/index.html,/tutorials/scripting/visual_script/index.html
|
||||
/getting_started/scripting/visual_script/nodes_purposes.html,/tutorials/scripting/visual_script/nodes_purposes.html
|
||||
/getting_started/scripting/visual_script/what_is_visual_scripting.html,/tutorials/scripting/visual_script/what_is_visual_scripting.html
|
||||
/getting_started/step_by_step/exporting.html,/tutorials/export/exporting_basics.html
|
||||
/getting_started/step_by_step/filesystem.html,/tutorials/scripting/filesystem.html
|
||||
/getting_started/step_by_step/godot_design_philosophy.html,/getting_started/introduction/godot_design_philosophy.html
|
||||
/getting_started/step_by_step/resources.html,/tutorials/scripting/resources.html
|
||||
/getting_started/step_by_step/scene_tree.html,/tutorials/scripting/scene_tree.html
|
||||
/getting_started/step_by_step/singletons_autoload.html,/tutorials/scripting/singletons_autoload.html
|
||||
/getting_started/workflow/assets/escn_exporter/animation.html,/tutorials/assets_pipeline/escn_exporter/animation.html
|
||||
/getting_started/workflow/assets/escn_exporter/index.html,/tutorials/assets_pipeline/escn_exporter/index.html
|
||||
/getting_started/workflow/assets/escn_exporter/lights.html,/tutorials/assets_pipeline/escn_exporter/lights.html
|
||||
/getting_started/workflow/assets/escn_exporter/material.html,/tutorials/assets_pipeline/escn_exporter/material.html
|
||||
/getting_started/workflow/assets/escn_exporter/mesh.html,/tutorials/assets_pipeline/escn_exporter/mesh.html
|
||||
/getting_started/workflow/assets/escn_exporter/physics.html,/tutorials/assets_pipeline/escn_exporter/physics.html
|
||||
/getting_started/workflow/assets/escn_exporter/skeleton.html,/tutorials/assets_pipeline/escn_exporter/skeleton.html
|
||||
/getting_started/workflow/assets/import_process.html,/tutorials/assets_pipeline/import_process.html
|
||||
/getting_started/workflow/assets/importing_audio_samples.html,/tutorials/assets_pipeline/importing_audio_samples.html
|
||||
/getting_started/workflow/assets/importing_images.html,/tutorials/assets_pipeline/importing_images.html
|
||||
/getting_started/workflow/assets/importing_scenes.html,/tutorials/assets_pipeline/importing_scenes.html
|
||||
/getting_started/workflow/assets/importing_translations.html,/tutorials/assets_pipeline/importing_translations.html
|
||||
/getting_started/workflow/assets/index.html,/tutorials/assets_pipeline/index.html
|
||||
/getting_started/workflow/best_practices/autoloads_versus_internal_nodes.html,/tutorials/best_practices/autoloads_versus_internal_nodes.html
|
||||
/getting_started/workflow/best_practices/data_preferences.html,/tutorials/best_practices/data_preferences.html
|
||||
/getting_started/workflow/best_practices/godot_interfaces.html,/tutorials/best_practices/godot_interfaces.html
|
||||
/getting_started/workflow/best_practices/godot_notifications.html,/tutorials/best_practices/godot_notifications.html
|
||||
/getting_started/workflow/best_practices/index.html,/tutorials/best_practices/index.html
|
||||
/getting_started/workflow/best_practices/introduction_best_practices.html,/tutorials/best_practices/introduction_best_practices.html
|
||||
/getting_started/workflow/best_practices/logic_preferences.html,/tutorials/best_practices/logic_preferences.html
|
||||
/getting_started/workflow/best_practices/node_alternatives.html,/tutorials/best_practices/node_alternatives.html
|
||||
/getting_started/workflow/best_practices/scene_organization.html,/tutorials/best_practices/scene_organization.html
|
||||
/getting_started/workflow/best_practices/scenes_versus_scripts.html,/tutorials/best_practices/scenes_versus_scripts.html
|
||||
/getting_started/workflow/best_practices/what_are_godot_classes.html,/tutorials/best_practices/what_are_godot_classes.html
|
||||
/getting_started/workflow/export/android_custom_build.html,/tutorials/export/android_custom_build.html
|
||||
/getting_started/workflow/export/changing_application_icon_for_windows.html,/tutorials/export/changing_application_icon_for_windows.html
|
||||
/getting_started/workflow/export/exporting_for_android.html,/tutorials/export/exporting_for_android.html
|
||||
/getting_started/workflow/export/exporting_for_dedicated_servers.html,/tutorials/export/exporting_for_dedicated_servers.html
|
||||
/getting_started/workflow/export/exporting_for_ios.html,/tutorials/export/exporting_for_ios.html
|
||||
/getting_started/workflow/export/exporting_for_uwp.html,/tutorials/export/exporting_for_uwp.html
|
||||
/getting_started/workflow/export/exporting_for_web.html,/tutorials/export/exporting_for_web.html
|
||||
/getting_started/workflow/export/exporting_pcks.html,/tutorials/export/exporting_pcks.html
|
||||
/getting_started/workflow/export/exporting_projects.html,/tutorials/export/exporting_projects.html
|
||||
/getting_started/workflow/export/feature_tags.html,/tutorials/export/feature_tags.html
|
||||
/getting_started/workflow/export/index.html,/tutorials/export/index.html
|
||||
/getting_started/workflow/export/one-click_deploy.html,/tutorials/export/one-click_deploy.html
|
||||
/getting_started/workflow/project_setup/project_organization.html,/tutorials/best_practices/project_organization.html
|
||||
/getting_started/workflow/project_setup/version_control_systems.html,/tutorials/best_practices/version_control_systems.html
|
||||
/learning/editor/2d_and_3d_keybindings.html,/getting_started/editor/2d_and_3d_keybindings.html
|
||||
/learning/editor/command_line_tutorial.html,/getting_started/editor/command_line_tutorial.html
|
||||
/learning/editor/index.html,/getting_started/editor/index.html
|
||||
/learning/editor/unity_to_godot.html,/getting_started/editor/unity_to_godot.html
|
||||
/learning/features/2d/2d_transforms.html,/tutorials/2d/2d_transforms.html
|
||||
/learning/features/2d/canvas_layers.html,/tutorials/2d/canvas_layers.html
|
||||
/learning/features/2d/custom_drawing_in_2d.html,/tutorials/2d/custom_drawing_in_2d.html
|
||||
/learning/features/2d/index.html,/tutorials/2d/index.html
|
||||
/learning/features/2d/particle_systems_2d.html,/tutorials/2d/particle_systems_2d.html
|
||||
/learning/features/2d/using_tilemaps.html,/tutorials/2d/using_tilemaps.html
|
||||
/learning/features/3d/3d_performance_and_limitations.html,/tutorials/3d/3d_performance_and_limitations.html
|
||||
/learning/features/3d/baked_lightmaps.html,/tutorials/3d/baked_lightmaps.html
|
||||
/learning/features/3d/environment_and_post_processing.html,/tutorials/3d/environment_and_post_processing.html
|
||||
/learning/features/3d/gi_probes.html,/tutorials/3d/gi_probes.html
|
||||
/learning/features/3d/high_dynamic_range.html,/tutorials/3d/high_dynamic_range.html
|
||||
/learning/features/3d/index.html,/tutorials/3d/index.html
|
||||
/learning/features/3d/introduction_to_3d.html,/tutorials/3d/introduction_to_3d.html
|
||||
/learning/features/3d/lights_and_shadows.html,/tutorials/3d/lights_and_shadows.html
|
||||
/learning/features/3d/reflection_probes.html,/tutorials/3d/reflection_probes.html
|
||||
/learning/features/3d/spatial_material.html,/tutorials/3d/spatial_material.html
|
||||
/learning/features/3d/using_gridmaps.html,/tutorials/3d/using_gridmaps.html
|
||||
/learning/features/animation/cutout_animation.html,/tutorials/animation/cutout_animation.html
|
||||
/learning/features/animation/index.html,/tutorials/animation/index.html
|
||||
/learning/features/animation/introduction_2d.html,/tutorials/animation/introduction_2d.html
|
||||
/learning/features/assetlib/index.html,/tutorials/assetlib/index.html
|
||||
/learning/features/assetlib/uploading_to_assetlib.html,/tutorials/assetlib/uploading_to_assetlib.html
|
||||
/learning/features/assetlib/using_assetlib.html,/tutorials/assetlib/using_assetlib.html
|
||||
/learning/features/assetlib/what_is_assetlib.html,/tutorials/assetlib/what_is_assetlib.html
|
||||
/learning/features/audio/audio_buses.html,/tutorials/audio/audio_buses.html
|
||||
/learning/features/audio/audio_streams.html,/tutorials/audio/audio_streams.html
|
||||
/learning/features/audio/index.html,/tutorials/audio/index.html
|
||||
/learning/features/gui/bbcode_in_richtextlabel.html,/tutorials/gui/bbcode_in_richtextlabel.html
|
||||
/learning/features/gui/custom_gui_controls.html,/tutorials/gui/custom_gui_controls.html
|
||||
/learning/features/gui/gui_skinning.html,/tutorials/gui/gui_skinning.html
|
||||
/learning/features/gui/index.html,/tutorials/gui/index.html
|
||||
/learning/features/gui/size_and_anchors.html,/tutorials/gui/size_and_anchors.html
|
||||
/learning/features/inputs/index.html,/tutorials/inputs/index.html
|
||||
/learning/features/inputs/inputevent.html,/tutorials/inputs/inputevent.html
|
||||
/learning/features/inputs/mouse_and_input_coordinates.html,/tutorials/inputs/mouse_and_input_coordinates.html
|
||||
/learning/features/math/index.html,/tutorials/math/index.html
|
||||
/learning/features/math/matrices_and_transforms.html,/tutorials/math/matrices_and_transforms.html
|
||||
/learning/features/math/vector_math.html,/tutorials/math/vector_math.html
|
||||
/learning/features/math/vectors_advanced.html,/tutorials/math/vectors_advanced.html
|
||||
/learning/features/misc/background_loading.html,/tutorials/misc/background_loading.html
|
||||
/learning/features/misc/binary_serialization_api.html,/tutorials/misc/binary_serialization_api.html
|
||||
/learning/features/misc/data_paths.html,/tutorials/misc/data_paths.html
|
||||
/learning/features/misc/encrypting_save_games.html,/tutorials/misc/encrypting_save_games.html
|
||||
/learning/features/misc/handling_quit_requests.html,/tutorials/misc/handling_quit_requests.html
|
||||
/learning/features/misc/index.html,/tutorials/misc/index.html
|
||||
/learning/features/misc/internationalizing_games.html,/tutorials/misc/internationalizing_games.html
|
||||
/learning/features/misc/locales.html,/tutorials/misc/locales.html
|
||||
/learning/features/misc/pausing_games.html,/tutorials/misc/pausing_games.html
|
||||
/learning/features/misc/saving_games.html,/tutorials/misc/saving_games.html
|
||||
/learning/features/networking/high_level_multiplayer.html,/tutorials/networking/high_level_multiplayer.html
|
||||
/learning/features/networking/http_client_class.html,/tutorials/networking/http_client_class.html
|
||||
/learning/features/networking/index.html,/tutorials/networking/index.html
|
||||
/learning/features/networking/ssl_certificates.html,/tutorials/networking/ssl_certificates.html
|
||||
/learning/features/physics/index.html,/tutorials/physics/index.html
|
||||
/learning/features/physics/kinematic_character_2d.html,/tutorials/physics/kinematic_character_2d.html
|
||||
/learning/features/physics/physics_introduction.html,/tutorials/physics/physics_introduction.html
|
||||
/learning/features/physics/ray-casting.html,/tutorials/physics/ray-casting.html
|
||||
/learning/features/platform/android_in_app_purchases.html,/tutorials/platform/android_in_app_purchases.html
|
||||
/learning/features/platform/index.html,/tutorials/platform/index.html
|
||||
/learning/features/platform/services_for_ios.html,/tutorials/platform/services_for_ios.html
|
||||
/learning/features/shading/index.html,/tutorials/shading/index.html
|
||||
/learning/features/shading/screen-reading_shaders.html,/tutorials/shading/screen-reading_shaders.html
|
||||
/learning/features/shading/shader_materials.html,/tutorials/shading/shader_materials.html
|
||||
/learning/features/shading/shading_language.html,/tutorials/shading/shading_language.html
|
||||
/learning/features/viewports/index.html,/tutorials/viewports/index.html
|
||||
/learning/features/viewports/multiple_resolutions.html,/tutorials/viewports/multiple_resolutions.html
|
||||
/learning/features/viewports/viewports.html,/tutorials/viewports/viewports.html
|
||||
/learning/scripting/c_sharp/c_sharp_basics.html,/getting_started/scripting/c_sharp/c_sharp_basics.html
|
||||
/learning/scripting/c_sharp/c_sharp_differences.html,/getting_started/scripting/c_sharp/c_sharp_differences.html
|
||||
/learning/scripting/c_sharp/c_sharp_features.html,/getting_started/scripting/c_sharp/c_sharp_features.html
|
||||
/learning/scripting/c_sharp/index.html,/getting_started/scripting/c_sharp/index.html
|
||||
/learning/scripting/gdscript/gdscript_advanced.html,/getting_started/scripting/gdscript/gdscript_advanced.html
|
||||
/learning/scripting/gdscript/gdscript_basics.html,/getting_started/scripting/gdscript/gdscript_basics.html
|
||||
/learning/scripting/gdscript/gdscript_format_string.html,/getting_started/scripting/gdscript/gdscript_format_string.html
|
||||
/learning/scripting/gdscript/gdscript_styleguide.html,/getting_started/scripting/gdscript/gdscript_styleguide.html
|
||||
/learning/scripting/gdscript/index.html,/getting_started/scripting/gdscript/index.html
|
||||
/learning/scripting/index.html,/getting_started/scripting/index.html
|
||||
/learning/scripting/visual_script/getting_started.html,/getting_started/scripting/visual_script/getting_started.html
|
||||
/learning/scripting/visual_script/index.html,/getting_started/scripting/visual_script/index.html
|
||||
/learning/scripting/visual_script/nodes_purposes.html,/getting_started/scripting/visual_script/nodes_purposes.html
|
||||
/learning/scripting/visual_script/what_is_visual_scripting.html,/getting_started/scripting/visual_script/what_is_visual_scripting.html
|
||||
/learning/step_by_step/animations.html,/getting_started/step_by_step/animations.html
|
||||
/learning/step_by_step/filesystem.html,/getting_started/step_by_step/filesystem.html
|
||||
/learning/step_by_step/godot_design_philosophy.html,/getting_started/step_by_step/godot_design_philosophy.html
|
||||
/learning/step_by_step/index.html,/getting_started/step_by_step/index.html
|
||||
/learning/step_by_step/instancing.html,/getting_started/step_by_step/instancing.html
|
||||
/learning/step_by_step/instancing_continued.html,/getting_started/step_by_step/instancing_continued.html
|
||||
/learning/step_by_step/intro_to_the_editor_interface.html,/getting_started/step_by_step/intro_to_the_editor_interface.html
|
||||
/learning/step_by_step/resources.html,/getting_started/step_by_step/resources.html
|
||||
/learning/step_by_step/scene_tree.html,/getting_started/step_by_step/scene_tree.html
|
||||
/learning/step_by_step/scenes_and_nodes.html,/getting_started/step_by_step/scenes_and_nodes.html
|
||||
/learning/step_by_step/scripting.html,/getting_started/step_by_step/scripting.html
|
||||
/learning/step_by_step/scripting_continued.html,/getting_started/step_by_step/scripting_continued.html
|
||||
/learning/step_by_step/singletons_autoload.html,/getting_started/step_by_step/singletons_autoload.html
|
||||
/learning/step_by_step/splash_screen.html,/getting_started/step_by_step/splash_screen.html
|
||||
/learning/step_by_step/ui_code_a_life_bar.html,/getting_started/step_by_step/ui_code_a_life_bar.html
|
||||
/learning/step_by_step/ui_game_user_interface.html,/getting_started/step_by_step/ui_game_user_interface.html
|
||||
/learning/step_by_step/ui_introduction_to_the_ui_system.html,/getting_started/step_by_step/ui_introduction_to_the_ui_system.html
|
||||
/learning/step_by_step/ui_main_menu.html,/getting_started/step_by_step/ui_main_menu.html
|
||||
/learning/step_by_step/your_first_game.html,/getting_started/step_by_step/your_first_game.html
|
||||
/learning/workflow/assets/import_process.html,/getting_started/workflow/assets/import_process.html
|
||||
/learning/workflow/assets/importing_audio_samples.html,/getting_started/workflow/assets/importing_audio_samples.html
|
||||
/learning/workflow/assets/importing_images.html,/getting_started/workflow/assets/importing_images.html
|
||||
/learning/workflow/assets/importing_scenes.html,/getting_started/workflow/assets/importing_scenes.html
|
||||
/learning/workflow/assets/importing_translations.html,/getting_started/workflow/assets/importing_translations.html
|
||||
/learning/workflow/assets/index.html,/getting_started/workflow/assets/index.html
|
||||
/learning/workflow/export/customizing_html5_shell.html,/getting_started/workflow/export/customizing_html5_shell.html
|
||||
/learning/workflow/export/exporting_for_android.html,/getting_started/workflow/export/exporting_for_android.html
|
||||
/learning/workflow/export/exporting_for_ios.html,/getting_started/workflow/export/exporting_for_ios.html
|
||||
/learning/workflow/export/exporting_for_pc.html,/getting_started/workflow/export/exporting_for_pc.html
|
||||
/learning/workflow/export/exporting_for_uwp.html,/getting_started/workflow/export/exporting_for_uwp.html
|
||||
/learning/workflow/export/exporting_for_web.html,/getting_started/workflow/export/exporting_for_web.html
|
||||
/learning/workflow/export/exporting_projects.html,/getting_started/workflow/export/exporting_projects.html
|
||||
/learning/workflow/export/feature_tags.html,/getting_started/workflow/export/feature_tags.html
|
||||
/learning/workflow/export/index.html,/getting_started/workflow/export/index.html
|
||||
/learning/workflow/export/one-click_deploy.html,/getting_started/workflow/export/one-click_deploy.html
|
||||
/learning/workflow/index.html,/getting_started/workflow/index.html
|
||||
/learning/workflow/project_setup/index.html,/getting_started/workflow/project_setup/index.html
|
||||
/learning/workflow/project_setup/project_organization.html,/getting_started/workflow/project_setup/project_organization.html
|
||||
/reference/2d_and_3d_keybindings.html,/learning/editor/2d_and_3d_keybindings.html
|
||||
/reference/_compiling.html,/development/compiling/
|
||||
/reference/_developing.html,/development/cpp/
|
||||
/reference/android_in_app_purchases.html,/learning/features/platform/android_in_app_purchases.html
|
||||
/reference/batch_building_templates.html,/development/compiling/batch_building_templates.html
|
||||
/reference/bbcode_in_richtextlabel.html,/learning/features/gui/bbcode_in_richtextlabel.html
|
||||
/reference/binary_serialization_api.html,/learning/features/misc/binary_serialization_api.html
|
||||
/reference/command_line_tutorial.html,/learning/editor/command_line_tutorial.html
|
||||
/reference/compiling_for_android.html,/development/compiling/compiling_for_android.html
|
||||
/reference/compiling_for_ios.html,/development/compiling/compiling_for_ios.html
|
||||
/reference/compiling_for_osx.html,/development/compiling/compiling_for_osx.html
|
||||
/reference/compiling_for_uwp.html,/development/compiling/compiling_for_uwp.html
|
||||
/reference/compiling_for_web.html,/development/compiling/compiling_for_web.html
|
||||
/reference/compiling_for_windows.html,/development/compiling/compiling_for_windows.html
|
||||
/reference/compiling_for_x11.html,/development/compiling/compiling_for_x11.html
|
||||
/reference/configuring_an_ide.html,/development/cpp/configuring_an_ide.html
|
||||
/reference/core_types.html,/development/cpp/core_types.html
|
||||
/reference/creating_android_modules.html,/development/cpp/creating_android_modules.html
|
||||
/reference/cross-compiling_for_ios_on_linux.html,/development/compiling/cross-compiling_for_ios_on_linux.html
|
||||
/reference/custom_modules_in_c++.html,/development/cpp/custom_modules_in_cpp.html
|
||||
/reference/faq.html,/about/faq.html
|
||||
/reference/gdscript.html,/learning/scripting/gdscript/gdscript_basics.html
|
||||
/reference/gdscript_more_efficiently.html,/learning/scripting/gdscript/gdscript_advanced.html
|
||||
/reference/gdscript_printf.html,/learning/scripting/gdscript/gdscript_format_string.html
|
||||
/reference/inheritance_class_tree.html,/development/cpp/inheritance_class_tree.html
|
||||
/reference/introduction_to_godot_development.html,/development/cpp/introduction_to_godot_development.html
|
||||
/reference/introduction_to_the_buildsystem.html,/development/compiling/introduction_to_the_buildsystem.html
|
||||
/reference/locales.html,/learning/features/misc/locales.html
|
||||
/reference/object_class.html,/development/cpp/object_class.html
|
||||
/reference/packaging_godot.html,/development/compiling/packaging_godot.html
|
||||
/reference/services_for_ios.html,/learning/features/platform/services_for_ios.html
|
||||
/reference/shading_language.html,/learning/features/shading/shading_language.html
|
||||
/reference/unity_to_godot.html,/learning/editor/unity_to_godot.html
|
||||
/reference/variant_class.html,/development/cpp/variant_class.html
|
||||
/tutorials/2d/_2d.html,/learning/features/2d/
|
||||
/tutorials/2d/_2d_gui.html,/learning/features/gui/
|
||||
/tutorials/2d/_2d_physics.html,/learning/features/physics/
|
||||
/tutorials/2d/custom_gui_controls.html,/learning/features/gui/custom_gui_controls.html
|
||||
/tutorials/2d/cutout_animation.html,/learning/features/animation/cutout_animation.html
|
||||
/tutorials/2d/gui_skinning.html,/learning/features/gui/gui_skinning.html
|
||||
/tutorials/2d/kinematic_character_2d.html,/learning/features/physics/kinematic_character_2d.html
|
||||
/tutorials/2d/physics_introduction.html,/learning/features/physics/physics_introduction.html
|
||||
/tutorials/2d/screen-reading_shaders.html,/learning/features/shading/screen-reading_shaders.html
|
||||
/tutorials/2d/size_and_anchors.html,/learning/features/gui/size_and_anchors.html
|
||||
/tutorials/2d/viewport_and_canvas_transforms.html,/learning/features/2d/2d_transforms.html
|
||||
/tutorials/3d/_3d.html,/learning/features/3d/
|
||||
/tutorials/3d/_3d_physics.html,/learning/features/physics/
|
||||
/tutorials/3d/fixed_materials.html,/learning/features/3d/fixed_materials.html
|
||||
/tutorials/3d/importing_3d_meshes.html,/learning/features/3d/importing_3d_meshes.html
|
||||
/tutorials/3d/importing_3d_scenes.html,/learning/features/3d/importing_3d_scenes.html
|
||||
/tutorials/3d/inverse_kinematics.html,/community/tutorials/3d/inverse_kinematics.html
|
||||
/tutorials/3d/lighting.html,/learning/features/lighting/lighting.html
|
||||
/tutorials/3d/materials.html,/learning/features/3d/materials.html
|
||||
/tutorials/3d/shader_materials.html,/learning/features/shading/shader_materials.html
|
||||
/tutorials/3d/shadow_mapping.html,/learning/features/lighting/shadow_mapping.html
|
||||
/tutorials/3d/vertex_animation/animating_thousands_of_fish.html,/tutorials/performance/vertex_animation/animating_thousands_of_fish.html
|
||||
/tutorials/3d/vertex_animation/controlling_thousands_of_fish.html,/tutorials/performance/vertex_animation/controlling_thousands_of_fish.html
|
||||
/tutorials/3d/vertex_animation/index.html,/tutorials/performance/vertex_animation/index.html
|
||||
/tutorials/3d/working_with_3d_skeletons.html,/community/tutorials/3d/working_with_3d_skeletons.html
|
||||
/tutorials/_math.html,/learning/features/math/
|
||||
/tutorials/_misc_tutorials.html,/learning/features/misc/
|
||||
/tutorials/_networking.html,/learning/features/networking/
|
||||
/tutorials/_plugins.html,/development/plugins/
|
||||
/tutorials/_shaders.html,/learning/features/shading/
|
||||
/tutorials/asset_pipeline/_asset_pipeline.html,/learning/workflow/
|
||||
/tutorials/asset_pipeline/_export.html,/learning/workflow/export/
|
||||
/tutorials/asset_pipeline/_import.html,/learning/workflow/assets/
|
||||
/tutorials/asset_pipeline/exporting_for_android.html,/learning/workflow/export/exporting_for_android.html
|
||||
/tutorials/asset_pipeline/exporting_for_ios.html,/learning/workflow/export/exporting_for_ios.html
|
||||
/tutorials/asset_pipeline/exporting_for_pc.html,/learning/workflow/export/exporting_for_pc.html
|
||||
/tutorials/asset_pipeline/exporting_for_uwp.html,/learning/workflow/export/exporting_for_uwp.html
|
||||
/tutorials/asset_pipeline/exporting_for_web.html,/learning/workflow/export/exporting_for_web.html
|
||||
/tutorials/asset_pipeline/exporting_images.html,/learning/workflow/assets/exporting_images.html
|
||||
/tutorials/asset_pipeline/exporting_projects.html,/learning/workflow/export/exporting_projects.html
|
||||
/tutorials/asset_pipeline/import_process.html,/learning/workflow/assets/import_process.html
|
||||
/tutorials/asset_pipeline/importing_audio_samples.html,/learning/workflow/assets/importing_audio_samples.html
|
||||
/tutorials/asset_pipeline/importing_fonts.html,/learning/workflow/assets/importing_fonts.html
|
||||
/tutorials/asset_pipeline/importing_textures.html,/learning/workflow/assets/importing_textures.html
|
||||
/tutorials/asset_pipeline/importing_translations.html,/learning/workflow/assets/importing_translations.html
|
||||
/tutorials/asset_pipeline/managing_image_files.html,/learning/workflow/assets/managing_image_files.html
|
||||
/tutorials/asset_pipeline/one-click_deploy.html,/learning/workflow/export/one-click_deploy.html
|
||||
/tutorials/assetlib/index.html,/community/asset_library/index.html
|
||||
/tutorials/assetlib/uploading_to_assetlib.html,/community/asset_library/uploading_to_assetlib.html
|
||||
/tutorials/assetlib/using_assetlib.html,/community/asset_library/using_assetlib.html
|
||||
/tutorials/assetlib/what_is_assetlib.html,/community/asset_library/what_is_assetlib.html
|
||||
/tutorials/content/making_trees.html,/tutorials/shaders/making_trees.html
|
||||
/tutorials/content/procedural_geometry/arraymesh.html,/tutorials/3d/procedural_geometry/arraymesh.html
|
||||
/tutorials/content/procedural_geometry/immediategeometry.html,/tutorials/3d/procedural_geometry/immediategeometry.html
|
||||
/tutorials/content/procedural_geometry/index.html,/tutorials/3d/procedural_geometry/index.html
|
||||
/tutorials/content/procedural_geometry/meshdatatool.html,/tutorials/3d/procedural_geometry/meshdatatool.html
|
||||
/tutorials/content/procedural_geometry/surfacetool.html,/tutorials/3d/procedural_geometry/surfacetool.html
|
||||
/tutorials/debug/debugger_panel.html,/tutorials/scripting/debug/debugger_panel.html
|
||||
/tutorials/debug/index.html,/tutorials/scripting/debug/index.html
|
||||
/tutorials/debug/overview_of_debugging_tools.html,/tutorials/scripting/debug/overview_of_debugging_tools.html
|
||||
/tutorials/engine/background_loading.html,/learning/features/misc/background_loading.html
|
||||
/tutorials/engine/data_paths.html,/learning/features/misc/data_paths.html
|
||||
/tutorials/engine/encrypting_save_games.html,/learning/features/misc/encrypting_save_games.html
|
||||
/tutorials/engine/handling_quit_requests.html,/learning/features/misc/handling_quit_requests.html
|
||||
/tutorials/engine/inputevent.html,/learning/features/inputs/inputevent.html
|
||||
/tutorials/engine/internationalizing_games.html,/learning/features/misc/internationalizing_games.html
|
||||
/tutorials/engine/mouse_and_input_coordinates.html,/learning/features/inputs/mouse_and_input_coordinates.html
|
||||
/tutorials/engine/multiple_resolutions.html,/learning/features/viewports/multiple_resolutions.html
|
||||
/tutorials/engine/pausing_games.html,/learning/features/misc/pausing_games.html
|
||||
/tutorials/engine/project_organization.html,/learning/workflow/project_setup/project_organization.html
|
||||
/tutorials/engine/saving_games.html,/learning/features/misc/saving_games.html
|
||||
/tutorials/engine/viewports.html,/learning/features/viewports/viewports.html
|
||||
/tutorials/gui/bbcode_in_richtextlabel.html,/tutorials/ui/bbcode_in_richtextlabel.html
|
||||
/tutorials/gui/control_node_gallery.html,/tutorials/ui/control_node_gallery.html
|
||||
/tutorials/gui/custom_gui_controls.html,/tutorials/ui/custom_gui_controls.html
|
||||
/tutorials/gui/gui_containers.html,/tutorials/ui/gui_containers.html
|
||||
/tutorials/gui/size_and_anchors.html,/tutorials/ui/size_and_anchors.html
|
||||
/tutorials/high_level_multiplayer.html,/learning/features/networking/high_level_multiplayer.html
|
||||
/tutorials/http_client_class.html,/learning/features/networking/http_client_class.html
|
||||
/tutorials/legal/complying_with_licenses.html,/about/complying_with_licenses.html
|
||||
/tutorials/making_plugins.html,/development/plugins/making_plugins.html
|
||||
/tutorials/matrices_and_transforms.html,/learning/features/math/matrices_and_transforms.html
|
||||
/tutorials/mesh_generation_with_heightmap_and_shaders.html,/community/tutorials/3d/mesh_generation_with_heightmap_and_shaders.html
|
||||
/tutorials/misc/background_loading.html,/tutorials/io/background_loading.html
|
||||
/tutorials/misc/binary_serialization_api.html,/tutorials/io/binary_serialization_api.html
|
||||
/tutorials/misc/change_scenes_manually.html,/tutorials/scripting/change_scenes_manually.html
|
||||
/tutorials/misc/data_paths.html,/tutorials/io/data_paths.html
|
||||
/tutorials/misc/encrypting_save_games.html,/tutorials/io/encrypting_save_games.html
|
||||
/tutorials/misc/gles2_gles3_differences.html,/tutorials/rendering/gles2_gles3_differences.html
|
||||
/tutorials/misc/handling_quit_requests.html,/tutorials/inputs/handling_quit_requests.html
|
||||
/tutorials/misc/instancing_with_signals.html,/tutorials/scripting/instancing_with_signals.html
|
||||
/tutorials/misc/internationalizing_games.html,/tutorials/i18n/internationalizing_games.html
|
||||
/tutorials/misc/jitter_stutter.html,/tutorials/rendering/jitter_stutter.html
|
||||
/tutorials/misc/locales.html,/tutorials/i18n/locales.html
|
||||
/tutorials/misc/pausing_games.html,/tutorials/scripting/pausing_games.html
|
||||
/tutorials/misc/running_code_in_the_editor.html,/tutorials/plugins/running_code_in_the_editor.html
|
||||
/tutorials/misc/saving_games.html,/tutorials/io/saving_games.html
|
||||
/tutorials/optimization/batching.html,/tutorials/performance/batching.html
|
||||
/tutorials/optimization/cpu_optimization.html,/tutorials/performance/cpu_optimization.html
|
||||
/tutorials/optimization/general_optimization.html,/tutorials/performance/general_optimization.html
|
||||
/tutorials/optimization/gpu_optimization.html,/tutorials/performance/gpu_optimization.html
|
||||
/tutorials/optimization/index.html,/tutorials/performance/index.html
|
||||
/tutorials/optimization/optimizing_3d_performance.html,/tutorials/performance/optimizing_3d_performance.html
|
||||
/tutorials/optimization/using_multimesh.html,/tutorials/performance/using_multimesh.html
|
||||
/tutorials/optimization/using_servers.html,/tutorials/performance/using_servers.html
|
||||
/tutorials/platform/android_in_app_purchases.html,/tutorials/platform/android/android_in_app_purchases.html
|
||||
/tutorials/plugins/android/android_plugin.html,/tutorials/platform/android/android_plugin.html
|
||||
/tutorials/plugins/android/index.html,/tutorials/platform/android/index.html
|
||||
/tutorials/plugins/gdnative/gdnative-c-example.html,/tutorials/scripting/gdnative/gdnative_c_example.html
|
||||
/tutorials/plugins/gdnative/gdnative-cpp-example.html,/tutorials/scripting/gdnative/gdnative_cpp_example.html
|
||||
/tutorials/plugins/gdnative/index.html,/tutorials/scripting/gdnative/index.html
|
||||
/tutorials/ray-casting.html,/learning/features/physics/ray-casting.html
|
||||
/tutorials/shading/advanced_postprocessing.html,/tutorials/shaders/advanced_postprocessing.html
|
||||
/tutorials/shading/godot_shader_language_style_guide.html,/tutorials/shaders/shaders_style_guide.html
|
||||
/tutorials/shading/index.html,/tutorials/shaders/index.html
|
||||
/tutorials/shading/migrating_to_godot_shader_language.html,/tutorials/shaders/converting_glsl_to_godot_shaders.html
|
||||
/tutorials/shading/screen-reading_shaders.html,/tutorials/shaders/screen-reading_shaders.html
|
||||
/tutorials/shading/shader_materials.html,/tutorials/shaders/shader_materials.html
|
||||
/tutorials/shading/shading_reference/canvas_item_shader.html,/tutorials/shaders/shader_reference/canvas_item_shader.html
|
||||
/tutorials/shading/shading_reference/index.html,/tutorials/shaders/shader_reference/index.html
|
||||
/tutorials/shading/shading_reference/particle_shader.html,/tutorials/shaders/shader_reference/particle_shader.html
|
||||
/tutorials/shading/shading_reference/shading_language.html,/tutorials/shaders/shader_reference/shading_language.html
|
||||
/tutorials/shading/shading_reference/spatial_shader.html,/tutorials/shaders/shader_reference/spatial_shader.html
|
||||
/tutorials/shading/visual_shaders.html,/tutorials/shaders/visual_shaders.html
|
||||
/tutorials/shading/your_first_shader/index.html,/tutorials/shaders/your_first_shader/index.html
|
||||
/tutorials/shading/your_first_shader/your_second_spatial_shader.html,/tutorials/shaders/your_first_shader/your_second_3d_shader.html
|
||||
/tutorials/ssl_certificates.html,/learning/features/networking/ssl_certificates.html
|
||||
/tutorials/step_by_step/_step_by_step.html,/learning/step_by_step/
|
||||
/tutorials/step_by_step/animations.html,/learning/step_by_step/animations.html
|
||||
/tutorials/step_by_step/filesystem.html,/learning/step_by_step/filesystem.html
|
||||
/tutorials/step_by_step/gui_tutorial.html,/learning/step_by_step/gui_tutorial.html
|
||||
/tutorials/step_by_step/instancing.html,/learning/step_by_step/instancing.html
|
||||
/tutorials/step_by_step/instancing_continued.html,/learning/step_by_step/instancing_continued.html
|
||||
/tutorials/step_by_step/resources.html,/learning/step_by_step/resources.html
|
||||
/tutorials/step_by_step/scene_tree.html,/learning/step_by_step/scene_tree.html
|
||||
/tutorials/step_by_step/scenes_and_nodes.html,/learning/step_by_step/scenes_and_nodes.html
|
||||
/tutorials/step_by_step/scripting.html,/learning/step_by_step/scripting.html
|
||||
/tutorials/step_by_step/scripting_continued.html,/learning/step_by_step/scripting_continued.html
|
||||
/tutorials/step_by_step/simple_2d_game.html,/learning/step_by_step/simple_2d_game.html
|
||||
/tutorials/step_by_step/singletons_autoload.html,/learning/step_by_step/singletons_autoload.html
|
||||
/tutorials/step_by_step/splash_screen.html,/learning/step_by_step/splash_screen.html
|
||||
/tutorials/threads/thread_safe_apis.html,/tutorials/performance/threads/thread_safe_apis.html
|
||||
/tutorials/threads/using_multiple_threads.html,/tutorials/performance/threads/using_multiple_threads.html
|
||||
/tutorials/vector_math.html,/learning/features/math/vector_math.html
|
||||
/tutorials/viewports/custom_postprocessing.html,/tutorials/shaders/custom_postprocessing.html
|
||||
/tutorials/viewports/multiple_resolutions.html,/tutorials/rendering/multiple_resolutions.html
|
||||
/tutorials/viewports/using_viewport_as_texture.html,/tutorials/shaders/using_viewport_as_texture.html
|
||||
/tutorials/viewports/viewports.html,/tutorials/rendering/viewports.html
|
||||
|
Reference in New Issue
Block a user