Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/workflows/redot-compatibility.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Redot compatibility

on:
push:
pull_request:

permissions:
contents: read

jobs:
redot-26-2:
runs-on: ubuntu-latest

steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Download Redot 26.2
shell: bash
run: |
set -euo pipefail
mkdir -p "$RUNNER_TEMP/redot"
curl --fail --location --retry 3 \
--output "$RUNNER_TEMP/redot/redot.zip" \
https://github.com/Redot-Engine/redot-engine/releases/download/redot-26.2-stable/Redot_v26.2-stable_linux_x64.zip
echo "f474d890806c41af15513cf5a8600243e241882e11b68dbb95660e3465b5b1e4 $RUNNER_TEMP/redot/redot.zip" | sha256sum --check
unzip -q "$RUNNER_TEMP/redot/redot.zip" -d "$RUNNER_TEMP/redot/bin"
REDOT_BIN="$(find "$RUNNER_TEMP/redot/bin" -type f -iname 'redot*' | head -n 1)"
chmod +x "$REDOT_BIN"
echo "REDOT_BIN=$REDOT_BIN" >> "$GITHUB_ENV"

- name: Verify engine version
run: '"$REDOT_BIN" --version'

- name: Import project and compile addon
shell: bash
run: |
set -euo pipefail
"$REDOT_BIN" --headless --path . --import 2>&1 | tee "$RUNNER_TEMP/redot-import.log"
if grep -E 'SCRIPT ERROR|Parse Error|Failed to load script|Failed loading resource' "$RUNNER_TEMP/redot-import.log"; then
exit 1
fi

- name: Run compatibility probe
shell: bash
run: |
set -euo pipefail
"$REDOT_BIN" --headless --path . --script res://tests/redot_compatibility.gd 2>&1 | tee "$RUNNER_TEMP/redot-probe.log"
if grep -E 'SCRIPT ERROR|Parse Error|Failed to load script|Failed loading resource' "$RUNNER_TEMP/redot-probe.log"; then
exit 1
fi
grep -F 'Twitcher Redot compatibility probe passed' "$RUNNER_TEMP/redot-probe.log"
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
# Twitcher

> **Redot compatibility fork:** This branch preserves Twitcher's Godot support while targeting
> Redot LTS 26.2. The editor plugin, setup wizard, and runtime `TwitchService` are validated with
> Redot `26.2.stable.official.4f5b14aba`.

[![Godot Asset Library](https://img.shields.io/badge/Godot%20Asset%20Library-Twitcher-blue?style=flat-square)](https://godotengine.org/asset-library/asset/2629) <!-- Replace YOUR_ASSET_ID -->
[![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](https://github.com/kanimaru/twitcher/blob/v2/LICENSE) <!-- Assuming MIT License -->
[![Twitch](https://img.shields.io/badge/Support_on_Twitch-kani_dev-purple?style=flat-square&logo=twitch)](https://www.twitch.tv/kani_dev/)
[![Documentation](https://img.shields.io/badge/Twitcher-Documentation-purple?style=flat-square&logo=readthedocs)](https://twitcher.kani.dev/)

**Seamless Twitch Integration for Godot 4.4+**
**Seamless Twitch Integration for Godot 4.4+ and Redot 26.2**

Twitcher provides a comprehensive toolkit to effortlessly connect your Godot Engine games,
overlays, or applications to the Twitch platform. Integrate real-time chat, respond to events like
Expand All @@ -29,6 +33,23 @@ follows and subscriptions, manage rewards, handle chat commands, and utilize the
* **Important:** The addon *must* reside in the exact path `res://addons/twitcher` for internal resources to load correctly.
2. **Enable Plugin:** Go to `Project -> Project Settings -> Plugins` and check the `Enable` box next to "Twitcher".

### Redot

Copy `addons/twitcher` to the same path in your Redot project, then enable Twitcher under
`Project -> Project Settings -> Plugins`. This fork uses the same public API and scene paths as
upstream Twitcher.

The development project can be checked with:

```powershell
redot --headless --path . --import
redot --headless --path . --script res://tests/redot_compatibility.gd
```

The probe loads the editor plugin, both setup-wizard variants, and an instantiated runtime
`TwitchService`. Live Twitch authentication and EventSub delivery require Twitch credentials and
are intentionally separate integration tests.

## Quick Start & Documentation

1. **Run Setup Wizard:** After enabling the plugin, the easiest way to configure authentication is via the Setup Wizard:
Expand Down
2 changes: 1 addition & 1 deletion addons/twitcher/editor/setup/page_game_authorization.gd
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func bootstrap() -> void:
var twitch_service: TwitchService = root_node.get_node(^"TwitchService")
twitch_service.token = TwitchEditorSettings.game_oauth_token
twitch_service.oauth_setting = TwitchEditorSettings.game_oauth_setting
EditorInterface.add_root_node(root_node)
get_tree().edited_scene_root = root_node


func _on_to_documentation_pressed() -> void:
Expand Down
2 changes: 1 addition & 1 deletion addons/twitcher/editor/setup/page_overlay_authorization.gd
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func bootstrap() -> void:
subscription.condition[key] = TwitchEditorSettings.default_user.id
subscription.set_meta(key + "_user", TwitchEditorSettings.default_user)

EditorInterface.add_root_node(root_node)
get_tree().edited_scene_root = root_node


func _set_authorized() -> void:
Expand Down
4 changes: 2 additions & 2 deletions addons/twitcher/plugin.cfg
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[plugin]

name="Twitcher"
description="A plugin to use Twitch API in Godot."
description="A plugin to use the Twitch API in Godot and Redot."
author="kani_dev"
version="2.5.1"
version="2.5.1-redot.1"
script="plugin.gd"
4 changes: 2 additions & 2 deletions project.godot
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ config_version=5

config/name="Twitcher"
run/main_scene="uid://5lyf04rwo1mf"
config/features=PackedStringArray("4.6", "Forward Plus")
config/icon="uid://pnr400301dhc"
config/features=PackedStringArray("26.2", "Redot")
config/icon="res://addons/twitcher/assets/twitcher-icon.svg"

[debug]

Expand Down
56 changes: 56 additions & 0 deletions tests/redot_compatibility.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
extends SceneTree

const REQUIRED_SCRIPTS: PackedStringArray = [
"res://addons/twitcher/plugin.gd",
]

const REQUIRED_SCENES: PackedStringArray = [
"res://addons/twitcher/editor/setup/page_game_authorization.tscn",
"res://addons/twitcher/editor/setup/page_overlay_authorization.tscn",
"res://addons/twitcher/twitch_service.tscn",
]


func _init() -> void:
call_deferred(&"_run_probe")


func _run_probe() -> void:
await process_frame
for path: String in REQUIRED_SCRIPTS:
if load(path) == null:
push_error("Failed to load required Twitcher script: %s" % path)
quit(1)
return

for path: String in REQUIRED_SCENES:
var scene: PackedScene = load(path)
if scene == null:
push_error("Failed to load required Twitcher scene: %s" % path)
quit(1)
return
if path.ends_with("twitch_service.tscn"):
var instance: Node = scene.instantiate()
if instance.get_script() == null:
push_error("Twitcher runtime scene root has no script: %s" % path)
instance.free()
quit(1)
return
root.add_child(instance)
instance.queue_free()
await process_frame
else:
var state: SceneState = scene.get_state()
var root_script: Script = null
for property_index: int in state.get_node_property_count(0):
if state.get_node_property_name(0, property_index) == &"script":
root_script = state.get_node_property_value(0, property_index)
break
if root_script == null:
push_error("Twitcher editor scene root has no script: %s" % path)
quit(1)
return

print("Twitcher Redot compatibility probe passed on Redot %s." % Engine.get_version_info().string)
await create_timer(3.0).timeout
quit()
1 change: 1 addition & 0 deletions tests/redot_compatibility.gd.uid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uid://fvbx576yivc2
6 changes: 3 additions & 3 deletions tests/sprite_frame_effect.tscn
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[gd_scene load_steps=3 format=3 uid="uid://ucvrw0jylplf"]
[gd_scene load_steps=3 format=3 uid="uid://ucvrw0jylplf"]

[ext_resource type="Script" uid="uid://dkppamu55n5j1" path="res://tests/sprite_frame_effect.gd" id="1_shaxi"]
[ext_resource type="SpriteFrames" uid="uid://da5n4t1o5ot67" path="res://documentation/create-credentials.gif" id="2_hw5pt"]
[ext_resource type="SpriteFrames" path="res://documentation/create-credentials.gif" id="2_hw5pt"]

[node name="SpriteFrameEffect" type="Control"]
layout_mode = 3
Expand All @@ -21,4 +21,4 @@ anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
bbcode_enabled = true
bbcode_enabled = true
Loading