Skip to main content

On Sale: GamesAssetsToolsTabletopComics
Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines
(+1)

Nice work, your game is so polished! I don't know how  you were able to integrate the tutorial with the gameplay so well but it works great. Love the art, animations, even the font choices, character unlocks. Everything.

Thanks! I took a bit of hints from how RimWorld does its tutorial. The game has conditionals checking for specific events and calls the tutorial prompt for it. The same sort of logic is set up for achievements! And if the event was already called, nothing happens.

Thanks to the whole game using coroutines for gameplay, halting the whole game loop to display prompts has been especially easy and that helped me integrate this sort of thing with little effort

Thanks for the info. How do you define your coroutines? Are you storing an array of actions or something, and then if one of those actions triggers a tutorial or achievement event, it pauses to process those before continuing with the rest of the actions in the array? Or is it even simpler than that?

Oh, it's using awaits / yields, yeah? Just read up a little more. That's much more manageable, heh.

Yeah pretty much! Here's the turn function which is all that stuff that happens between choosing a horror and checking if someone died from it. (there's coroutine stuff there for tutorials and such as well!) So each turn in the main loop is basically just 

var loser:Player = await turn(remaining_players)

and then that's

## Returns the player with the lowest score 
func turn(_selected_players:Array = []) -> Player:
    set_active_players(_selected_players)
    var chosen_actions:Dictionary[Player, Action] = await get_chosen_actions(_selected_players)
    await trigger_actions(chosen_actions.values(), Effect.Trigger.BeforeScoring)
    var score_buckets:Dictionary[int, Array] = score_actions(chosen_actions)
    var losers:Array = get_lowest_scoring_players(score_buckets)
    if losers.size() > 1:
        await tutorial.trigger(Tutorial.Flag.Ties)
        await trigger_actions(get_all_actions(), Effect.Trigger.Tied)
        Game.play_sfx(Game.SFX.Boom)
        return await turn(losers)
    return losers[0]

Cool! Thanks for sharing. It's like a recursive search for the loses. What's `get_all_action()` doing, does it just get the actions for the losers? Or is that waiting for input from the player to choose their actions?

It's returning an array of action cards the players have played, but I suppose I could've totally just done chosen_actions.values() now that I'm looking it over, it's totally due for a bit of a refactor I just never stopped to think about it lol

Oh wait! It's doing more than that, it returns all actions in the players hands. This was meant for an action effect that I never actually added. In theory a card could do something extra if a tie triggers while it's in your hand. I do have cards that have a bonus when playing during ties but that's a different mechanism. I think I was planning on the growth ability to be a tie only thing but that made it way too slow, and tbh even per turn felt too slow which is why unlockable characters growth cards grow way faster.