jengine-adventure
Point-and-click adventure - verbs, rooms that remember, and a game proved winnable from every state it can reach.
| Kind | Project package: linked into the builds of the projects that list it |
| Source | packages/jengine-adventure |
| Version | 0.1.0 |
| Entry point | jengine_adventure::AdventurePackage |
| Script namespace | Adventure |
| Listed by | projects/arcade-classics |
Using it
Section titled “Using it”List it in the top-level "packages" array of project.jengine:
{ "packages": [ { "name": "jengine-adventure", "source": { "type": "path", "path": "../../packages/jengine-adventure" } } ]}Then rebuild the editor viewport for the project (jengine viewport-build projects/<name>, or the
editor’s Rebuild viewport banner). Native and web builds link it on their own.
A scene that uses its components must be a v2 scene ("version": 2): a v1 scene has no field
for a package component and keeps it as inert custom data.
A script can check that the package is linked with if Adventure == nil then return end.
Components
Section titled “Components”| Scene key | Rust type | |
|---|---|---|
cl_game | Drive | package only: needs a v2 scene |
Script commands
Section titled “Script commands”Commands run in every runtime and return nothing; a package publishes what scripts read onto components (see the notes below). The flat name also works.
| Call | Flat name |
|---|---|
Adventure.start(e) | cl_start |
Adventure.quit(e) | cl_quit |
Adventure.end_talk(e) | cl_end_talk |
Adventure.verb(e, verb) | cl_verb |
Adventure.point(e, x, y) | cl_point |
Adventure.click(e, x, y) | cl_click |
Adventure.say(e, line) | cl_say |
Scenes that use it
Section titled “Scenes that use it”projects/arcade-classics/assets/scenes/lane.scene
From packages/jengine-adventure/src/lib.rs.
Crooked Lane - a point-and-click adventure.
- [
world]: the game as a state machine - a room, an item bitset, a flag bitset. - [
solve]: proving it winnable from every state it can reach. - [
talk]: conversations, and the one hole in that proof. - [
content]: loading it from data tables, ids resolved to indices.
What this game is here to prove
Section titled “What this game is here to prove”Cursor work. A point-and-click is a game about pointing: what is under
the cursor, what the current verb would do to it, and the sentence that
describes it. All of that lives here, in Drive::look_at, and it is one
hit test over one list - hotspots, exits and inventory icons together.
Keeping them on one path was a deliberate choice against the obvious
alternative, which is hotspots in the world and the inventory in a .gui.
Two hit-testing paths means two sets of coordinate conventions, two z
orders, and two places for “what is under the cursor” to disagree - and the
player cannot see any of that, they just find that clicking the crowbar
sometimes does nothing. So the GUI owns the verb bar, the status line and
the conversation; everything you can point at a thing with is a sprite.
A hint that cannot lie. Because solve knows the real distance from
every reachable state to a win, the game can say how many moves are left and
be right. The usual version of this is an author writing “you’re getting
warmer” next to a puzzle and hoping.
Rooms are not scenes, and that is on purpose
Section titled “Rooms are not scenes, and that is on purpose”It would be tempting to make each room a scene, and it would prove nothing: Brisk Errands already loads a scene every four seconds and already found the bug that lives there (BUGS #149). A room here is a background swap inside one scene, which is also what most of the genre actually does - a room is not a level. The state therefore lives in the component and needs nothing special to survive walking about.
Component ("version": 2 scenes)
Section titled “Component ("version": 2 scenes)”cl_game, on an entity with a transform.
"cl_game": { "tables": { "rooms": "data/cl_rooms", "items": "data/cl_items", "flags": "data/cl_flags", "rules": "data/cl_rules", "talk": "data/cl_talk" }, "sheet": "atlases/lane.png"}Script commands
Section titled “Script commands”| Call | Does |
|---|---|
Adventure.start(e) | begin |
Adventure.verb(e, verb) | choose a verb: look, take, use, talk, open |
Adventure.point(e, x, y) | the cursor moved - resolves what is under it |
Adventure.click(e, x, y) | act with the current verb at that point |
Adventure.say(e, line_id) | choose a line in a conversation |
Adventure.end_talk(e) | leave one |
Adventure.quit(e) | give up |