Rez v1.7.0 — open source language & engine for making procedural narrative games

If I set a background-image on a <div> within the @scene layout, would the background image cover the whole screen? I don’t understand @scene layout, honestly - not yet.


I have a question about updating Rez projects. How do I update Rez projects stored locally? Do I need to download the new Rez binary on GitHub and start over?


What kind of game are you trying to create?

I’m inspired by VNs. I want to make a VN-like game that has an event-driven narrative instead of a branching narrative.

I was trying to author the game’s narrative as branches in Twine and got stuck because the player in my game moves through a map. This would mean each branch needs to lead to a new branch which allows the player to move anywhere else in the map. Maybe there’s a way to solve this, but it got very messy.

If you see my previous post you don’t need to. Use the on_scene_start handler and set the body.backgroundImage to any given @assets $dist_path.

You can use any of the document.body.style assignments such as backgroundRepeat to get whatever effect you need.

You shouldn’t need to do anything to the project. I think all you need to do is download the v1.5.3 binary package for your platform.

When I was playing with this I used something like:

@alias location = object

@defaults location {
  %% what attributes do you want a location to have, e.g.
  name: _
}

@location loc_somewhere {
  name: "Some place"
  description: """
    A maze of twisty passages all alike
  """
  connects_to: [#loc_somewhere_else …]
}

@card c_some_card {
  location_id: #loc_somewhere
}

or

@scene sc_scene {
  location_id: #loc_somewhere
}

So I use an object to store data about the location and specify the location of any scene/card where location is meaningful.

1 Like

The layout system is conceptually simple:

game.layout
  embeds current_scene.layout
    embeds current_card.content

In the top-level template (in index.html) you have:

<body>
  <div id="game-container"></div>
</body>

The @game layout gets rendered and inserted into the #game-container div.

So the @game element expects a layout: template attribute which must contain a ${content} expression somewhere in it. E.g.

@game {
  layout: ```
  <!-- Main Content -->
  <section class="main-content is-fullheight">
    <div class="container">${content}</div>
  </section>
  <!-- End -->
  ```
}

Note that Rez uses Bulma so you’ll see some Bulma classes like is-fullheight, columns, column, is-two-fifths and so on spread through the markup.

What is ${content} in the context of the @game layout?

It’s the rendered layout of the current @scene. So every @scene must also have a layout: template attribute and this too must contain at least the expression ${content}:

@scene a_scene {
  blocks: [#c_sidebar]
  layout: ```
  <div class="columns">
    <div class="column is-two-fifths">${c_sidebar}</div>
    <div class="column">${content}</div>
  </div>  ```
}

In the context of the @scene layout the ${content} expression is the rendered value of the current @cards content: template attribute.

@card a_card {
  content: ```
  stuff goes here
  ```
}

If you inspect the rendered markup you will see that there are some divs setup for scenes and cards that you can target with CSS and which are used for features like links and forms. You don’t need to create those yourself.

You can see here the div’s with class game and scene (in the future they will be rez-game and rez-scene). You won’t find a div with class card because that conflicts with Bulma’s .card CSS class, however you will see one with class rez-card and rez-active-card. That’s the card.

So you might put things that should always be visisble (things like game title, player info, current day, location, and so on) in the game layout. Then scene-specific layout in the scene layout. Or do everything in the scene layout and ignore game layout altogether. Or whatever combination makes sense for your game.

I hope this helps.

2 Likes

I come back to this because I am in agreement. I’ve noticed recently that I am often clicking through “walls of text” even when I don’t want to. I’m playing ‘Star Sector’ ATM and I’ve found myself clicking through the exposition to get back to the “mission”.

What I’ve had to do is actually start reading these passages out because, to some extent, they do matter and I want to know what’s in them.

Possibly a peculiarity for me is that I have moderate aphantasia making long prose descriptions often more annoying than useful.

2 Likes

Hi,

It’s possible that i suffer from aphantasia as well. Perhaps it’s why i really enjoy graphics in IF games. Personally, i feel it enriches the story and experience. But i know, at the same time, there are people that find the graphics a distraction to the story - which is the total opposite.

Regarding text, what I’ve discovered;

I am striving to maintain the long-form IF narrative but in the presence of pictures. This means having a reasonable amount of text on screen simultaneously with images. The situation for general VNs is a lot less text. More of the short-form style from comics.

Some games have a text output box where a bunch of text appears almost line by line, a bit at a time. Having to click though several "more"s is annoying i find.

When dealing with writers, i find they generate “walls of text” fast. Lots of it. After all, that’s what they do :slight_smile:

I am discovering ways to break up “walls of text” by adding interactivity. For example, a whole pile of exposition should never be in one go, but split up and added to descriptions of things in the scene or story.

A lot of general story background can be put into character dialogue. Most dialogue will have some background info for the character, some general stuff can be hidden in there too. Or just put from the character POV.

The same goes for major story beats, where there is a lot of text generated in one story scene. This needs to be spread out, or the player will get bored.

Because we are making non-linear stories, it’s necessary to maintain the player interest by allowing them to follow their agency. As I’m starting to put the parser on the back seat, it means having more things to click on and more dialogue options per unit of text. What I refer to as the text cadence. Too much text at once starves the player of agency and therefore interest.

If the player’s interest is lost, the game will die.

Demo:

Dr Who

This game is not a great example of writing, but i refer to it to show how i am tackling the “text and picture problem”. You will see how there is still 1 or 2 paragraphs of text at the same time as a full size picture.

This was not easy to achieve, as i must maintain text readability whilst not obscuring too much image. Nevertheless, this is about the most text i can fit at any time on screen. Which gives a rule of thumb about how much text is possible between player interactions.

2 Likes

Pet hate of mine too.

Agreed. In one game I am working on I’ve broken up the exposition into a set of dreams.

Screenwriting has, I think, a maxim around “show don’t tell” and I think to some extent that applies here too.

Agreed about agency although I am less certain about interest=f(agency) for any simple value of f. I mean people enjoy reading novels where agency is pretty close to 0 (unless we count not turning the page) but I do agree that providing greater agency, allowing the player to tell a story they are more involved in, is a good thing.

1 Like

I’ve released Rez v1.5.4 which is mainly a QoL release. Now that I am using Rez in anger I am finding more rough edges that need fixing!

  • No longer need to special case $player with $global: true
  • Stdlib: adds Number#round_to_nearest
  • ^i{} initializer now implemented wrapped as immediate function
  • Adds RezDie#open_roll
  • Calling event handlers converts false into RezEvent.noop()
  • Adds events to RezGame for scene/end, scene/pause, and scene/resume
  • All Rez CSS classes now have a “rez-” prefix
  • Adds bugged missing accessors
2 Likes

Hi Matt,

It’s good to hear you’re working on your own Rez game. Can Rez do graphics? I could render some pictures for you if you like. Or perhaps a cover.

2 Likes

A cover would be neat, thank you. When the game is a little closer to something playable I’d appreciate that.

The game is is still nascent but I am actually building it now :grinning:. I’ve also done 3 live building sessions though they dont make for great TV!

In terms of graphics Rez creates a JS app that generates markup so it can do whatever graphics you can do in a browser.

It has an element @asset for declaring assets that automatically handle paths, media types and metadata (e.g. width & height) for you, so images are easy.

I’ve also made use of dynamically generated SVG for drawing a map of the star sector. In a an demo I made, I also used a @timer element to animate an SVG graphic.

1 Like

ok, let me know a bit later what sort of cover you had in mind.

Sounds like your game is a sci-fi. If so, that’s good, I have a ton of licensed sci-fi assets.

1 Like

Thanks, I will.

Yes the game is code-named Fleet Commander and is a sci-fi procedural narrative game about running fleet operations in an isolated sector of space that has suddenly become rather hot.

Yesterday I spent some time working on NPC psychology, I think I now have a model that will generate interesting behaviours both in terms of mission performance but also inter-officer relationships. I have to actually define how they are going to work in the game now.

A problem I often struggle with is designing things that are too complex to build, chiselling away at an edge and then getting disheartened. So what I am trying to learn to do instead is build a sketch of the big idea and say “good enough” until I have time to do a better job.

2 Likes

Hi,

It’s interesting you talk about making things “good enough”;

When I started building Strand, the design remit wasn’t “lets make the best IF system” or anything like that. In fact, I’m happy to admit the shortcomings of the system.

Instead, i focused on making something productive. Or what you would perhaps call “good enough”. The idea was I want Strand to build simple things fast, fun and easy rather than having the 1% of complex things poison the design of everything else.

I also wanted the DSL syntax as simple as possible. This wasn’t just about technical vs non-technical, it was simply the less technical it is, the easier it is to write regardless.

So i chucked everything out and started from the very, very basics. Turns out this can be a good idea. Quite often the other bits can be added later in any case.

I can rattle out short games in a day now - with graphics and sound!

It’s all about keeping thing simple, and that’s what I highly recommend to anyone else when approaching a problem.

Looking forward to seeing Fleet Commander!

2 Likes

I think I understand the inspiration for Fleet Commander now. :wink:

1 Like

You know, I hadn’t considered allowing you to romance your captains but now you bring this up…

1 Like

I’ve gone back on forth on the idea of inheritance in Rez. Bearing in mind that Rez is transpiled into Javascript.

Up until now I’ve had a way of setting parent objects and what that did was to copy attributes from the parent into the child at compile time:

@object named {
  name: ^p{return `${this.given_name} ${this.family_name}`;}
}

@actor joe_smith<named> {
  given_name: "Joe"
  family_name: "Smith"
}

The object #joe_smith gets a name attribute from #named. It kind of works but it has downsides that were annoying me. The code was pretty ugly and it meant the attribute getting duplicated everywhere it is used. Close, but I was not happy.

I tried implementing inheritance using Javascript prototypes but it turns out that properties created by Object.defineProperty() are treated differently so that calling name on an object which doesn’t define it won’t find it in the prototype either! I could have lived with a single parent (you can only have one prototype) if this had worked.

So, what have I ended up with?

@mixin named {
  name: ^p{return `${this.given_name} ${this.family_name}`;}
}

@actor joe_smith<#named> {
  given_name: "Joe"
  family_name: "Smith"
}

Again #joe_smith has the name property but this is now done at runtime during RezBasicObject.init(). An object declaring one or more mixins dynamically gets a copy of the properties and functions from those mixins.

The new @mixin element only accepts property and function attributes. It is only for sharing functionality, not data.

This has achieved what I was looking for. At least for now. I’ll push this in Rez v1.6

1 Like

I’ve released v1.6.0 with the new @mixin element for sharing implementation between elements.

This is intended to make it easier to use procedurally generated elements. I’m doing a lot of that in Fleet Commander.

1 Like

I’ve released v1.6.1 with the following changes:

  • Adds addCopy() as a convenient for cloning with an automatic id and adding to the game (plus some other conveniences)
  • Adds unmapObject() to remove dynamically created objects
  • RezDieRoll supports exploding dice
  • Validates @mixin attributes
  • Removes the ^{} code block as a sugar for function()

These changes have come up mainly from creating my WorldBuilder which is doing a lot of object cloning.

FWIW, I use inheritance a lot in Strand. Without it, things would be a lot more annoying.

I have multiple inheritance and objects like to inherit from all sorts of bases to include behaviour. Each of my standard bases injects a bunch of functionality, so GETTABLE and CONTAINER and SURFACE (aka supporter) do what you’d expect and you can just mix them in as required.

It got so sophisticated that you can inherit objects from choices and choices from objects. At first this seems totally weird, but it actually makes sense.