Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: enable ESCItem to use custom ESCEvents written in GDScript #712

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

bolinfest
Copy link
Contributor

feat: enable ESCItem to use custom ESCEvents written in GDScript

My high-level goal is to use my own scripting language for Escoria.
This goes back to some of my original work on RoomScript:

#558

as well as this prototype to generate ESC from my own scripting language:

https://github.com/bolinfest/alt-esc-prototype/

Because #558 was a large change that was impractical to upstream,
I decided to try to rework things as a much smaller diff so that
I could unblock myself without having to maintain a fork.
The crux of this commit is only a two-line change to esc_object_manager.gd.

The rest of the changes in the commit are updates to the demo to illustrate how
the feature could be used, as it changes r3_l_exit to be a custom instance of
ESCItem that implements the new, optional generate_events() function so it
can return its own Dictionary to map event names to ESCEvent instances.

Though in practice, I would not expect to author this sort of code by hand.
Instead, I would have my own scripting language from which I would generate
files such as l_door.gd and l_door_exit_scene.gd.

Though as illustrated by _compile_event_from_esc(), I could
start by generating ESC instead of going straight to GDScript.
For example, my input language might be:

room room03 {
  item l_door {
    event exit_scene {
      // ESC
      change_scene "res://game/rooms/room02/room02.tscn"
    }
  }

  item r_door {
    event exit_scene {
      // ESC
      change_scene "res://game/rooms/room04/room04.tscn"
    }
  }
}

And from this, it would be fairly straightforward to generate these two .gd files:

# game/rooms/room03/l_door.gd
extends ESCItem

func generate_events() -> Dictionary:
    return {
        "exit_scene": escoria.esc_compiler.compile([
            ":exit_scene",
            "change_scene \"res://game/rooms/room02/room02.tscn\"",
        ]).events["exit_scene"],
    }

and:

# game/rooms/room03/r_door.gd
extends ESCItem

func generate_events() -> Dictionary:
    return {
        "exit_scene": escoria.esc_compiler.compile([
            ":exit_scene",
            "change_scene \"res://game/rooms/room04/room04.tscn\"",
        ]).events["exit_scene"],
    }

Initially, I admit this does not buy much other than making it possible
to define events for multiple items in one file. Though over time, I
would like to be able to more sophisticated things like you see in:

https://github.com/grumpygamer/DeloresDev/blob/master/Scripts/Rooms/MainStreet.dinky

While I know it is possible to extend ESC by creating my own instances of
ESCCommand, I would prefer to have the freedom to experiment with a
broarder array of constructs.

My high-level goal is to use my own scripting language for Escoria.
This goes back to some of my original work on RoomScript:

godot-escoria#558

as well as this prototype to generate ESC from my own scripting language:

https://github.com/bolinfest/alt-esc-prototype/

Because godot-escoria#558 was a large change that was impractical to upstream,
I decided to try to rework things as a much smaller diff so that
I could unblock myself without having to maintain a fork.
The crux of this commit is only a two-line change to `esc_object_manager.gd`.

The rest of the changes in the commit are updates to the demo to illustrate how
the feature could be used, as it changes `r3_l_exit` to be a custom instance of
`ESCItem` that implements the new, optional `generate_events()` function so it
can return its own `Dictionary` to map event names to `ESCEvent` instances.

Though in practice, I would not expect to author this sort of code by hand.
Instead, I would have my own scripting language from which I would generate
files such as `l_door.gd` and `l_door_exit_scene.gd`.

Though as illustrated by `_compile_event_from_esc()`, I could
start by generating ESC instead of going straight to GDScript.
For example, my input language might be:

```
room room03 {
  item l_door {
    event exit_scene {
      // ESC
      change_scene "res://game/rooms/room02/room02.tscn"
    }
  }

  item r_door {
    event exit_scene {
      // ESC
      change_scene "res://game/rooms/room04/room04.tscn"
    }
  }
}
```

And from this, it would be fairly straightforward to generate these two `.gd` files:

```gdscript
# game/rooms/room03/l_door.gd
extends ESCItem

func generate_events() -> Dictionary:
    return {
        "exit_scene": escoria.esc_compiler.compile([
            ":exit_scene",
            "change_scene \"res://game/rooms/room02/room02.tscn\"",
        ]).events["exit_scene"],
    }
```

and:

```gdscript
# game/rooms/room03/r_door.gd
extends ESCItem

func generate_events() -> Dictionary:
    return {
        "exit_scene": escoria.esc_compiler.compile([
            ":exit_scene",
            "change_scene \"res://game/rooms/room04/room04.tscn\"",
        ]).events["exit_scene"],
    }
```

Initially, I admit this does not buy much other than making it possible
to define events for multiple items in one file. Though over time, I
would like to be able to more sophisticated things like you see in:

https://github.com/grumpygamer/DeloresDev/blob/master/Scripts/Rooms/MainStreet.dinky

While I know it is possible to extend ESC by creating my own instances of
`ESCCommand`, I would prefer to have the freedom to experiment with a
broarder array of constructs.
@BHSDuncan
Copy link
Collaborator

This could be very interesting and would accomplish the kind of extension you're after. And I think it could become even more useful after we get the mechanics of the updated ESC language/interpreter finished. Eg the power to coordinate across multiple events so each one doesn't necessarily need to exist in isolation to each other.

@bolinfest you may want to take a look at the "cfg-interpreter" branch to see how we're changing the language and how the interpreter works. I don't think it necessarily affects this PR but it might (or might not) give some ideas as to what you can do w this in the future.

@bolinfest
Copy link
Contributor Author

@BHSDuncan I just picked a commit at random in the branch and found:

17e0717

Nice to see if and elif in there!

@BHSDuncan
Copy link
Collaborator

Thanks! The idea is to make ESC script more like GDScript with common conventions. Basic loops, conditionals, scoping, etc. Always looking for feedback on what should be included for the first pass. We'll add to it as time goes on but we want the first release of it to be as useful as possible without breaking the bank, so to speak.

The interrupter also operates "JIT" for the most part, so we're moving away from compiling events when a room is entered and executing the cached events and having events executed line by line as they happen.

bolinfest added a commit to bolinfest/alt-esc-prototype that referenced this pull request Oct 26, 2023
Note this intends to complement the work I am proposing for Escoria in
godot-escoria/escoria-demo-game#712
@bolinfest
Copy link
Contributor Author

I updated the prototype of my script parser to generate GDScript that uses the new generate_events() API:

https://bolinfest.github.io/alt-esc-prototype/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants