MCParks / Achievables

A Java library for specifying video game achievement-like "Achievables" complete with a Groovy-based programming language for defining them
GNU Affero General Public License v3.0
1 stars 0 forks source link

DSL Modules #1

Open RyanHecht opened 3 months ago

RyanHecht commented 3 months ago

Currently, in order to write the "Magic Kingdom Mountaineer" achievement, you must write this:

achievement {
    name "Magic Kingdom Mountaineer"
    description "Ride the three mountains of Magic Kingdom without warping or teleporting"
    icon "IRON_SPADE:20"
    reward "MONEY:500"

    initialState {
        rodeSpaceMountain: false
        rodeBigThunderMountain: false
        rodeSplashMountain: false
        warpedOrTeleported: false
    }

    activators {
        state.rodeSpaceMountain && state.rodeBigThunderMountain && state.rodeSplashMountain
    }

    deactivators {
        state.warpedOrTeleported
    }

    events {
        on("CompleteRideEvent") {
            if (event.rideId == 1) {
                state.rodeSpaceMountain = true
            }
            if (event.rideId == 2) {
                state.rodeBigThunderMountain = true
            }
            if (event.rideId == 3) {
                state.rodeSplashMountain = true
            }
        }
        on("TeleportPlayerToPlayerEvent") {
            state.warpedOrTeleported = true
        }
        on("PlayerWarpEvent") {
            state.warpedOrTeleported = true
        }
    }
}

This is very verbose, and one can imagine LOTS of achievements that would want to use the notion of completing rides and disallowing warping/teleporting. I propose a modular system for the BIGAL DSL that would make the "Magic Kingdom Mountaineer" achievement look like this:

achievement {
    name "Magic Kingdom Mountaineer"
    description "Ride the three mountains of Magic Kingdom without warping or teleporting"
    icon "IRON_SPADE:20"
    reward "MONEY:500"

    activators {
        completeRide(id: 1) && completeRide(id: 2) && completeRide(id: 3)
    }

    deactivators {
        warpOrTeleport()
    }
}

and modules that look something like this:

module { id ->
  name "completeRide"

  initialState {
      rodeIt: false      
  }

  activators {
    state.rodeIt
  }

  events {
    on("CompleteRideEvent") {
            if (event.rideId == id) {
                state.rodeIt = true
            }
        }
  }
}

It's important that the state scopes don't conflict, I should be able to use the completeRide module in a module or achievement that has its own rodeIt variable.

casptyche commented 1 month ago

Is this still desired?

RyanHecht commented 1 month ago

@casptyche Yes! This is definitely the next big feature I want to add to the language

...to be honest I just made this issue because I was playing with Copilot Workspace :p