End screen
Show a victory, defeat or game-over screen with a recap, Play again, Main menu and Credits buttons and scrolling credits; choose what ends the game, which stats to list and which texts to show.
End screen, recap and credits (ui.endscreen) #
Part of the menus and screens guide.
What it is for #
ui.endscreen ends a game without any interface of your own. It opens on the events you list (victory, defeat, missions, the death of the player, the finished phase, the end of the game flow of game.engine), shows the result, a recap (play time, stats read from variables, places and quests of game.engine, lines from other kits) and its buttons, then the credits. It builds one model; every engine draws it (the web player draws it as a ui.webui fragment). The kit needs ui.menu and game.engine: Play again and Main menu go through the menu.
Turn it on #
gripforge_gamekit_install { project_id: "gkp_…", id: "ui.endscreen" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "ui.endscreen",
config: { "onDeath": true, "buttons": ["retry", "menu", "credits", "quit"] } }
With the defaults, emitting game.won opens the victory screen and game.lost the defeat screen.
First example #
<!-- test: kits/game_engine/host/tests/ui_endscreen.rs::an_event_ends_the_game_and_the_screen_pauses_it_once_drawn --> A game emits game.lost. The view then has the result defeat, the title "Defeat" (in French "Défaite"), a recap that starts with the play time and then the score. The game keeps playing until an interface says it draws the screen (attach); then it is paused, and hide resumes it.
{ "op": "call", "service": "ui.endscreen", "method": "view", "args": ["fr"] }
Settings and defaults #
| Setting | Type | Default | Meaning |
|---|---|---|---|
template | text | classic | web look: classic, gothic, cinematic, tactical, arcade |
victoryEvents | list | ["game.won"] | events that end the game with a victory (patterns allowed: *, boss.*) |
defeatEvents | list | ["game.lost"] | events that end the game with a defeat |
missions | list | [] | missions whose completion is a victory and failure a defeat (* and prefix patterns) |
onFinished | boolean | true | open when the game enters the finished phase (result read from run.result, course.result, mission.status) |
onDeath | boolean | false | player.died is a defeat |
showTime | boolean | true | show the play time in the recap |
stats | list | score, money, room reached | recap lines { id, var, label: { en, fr }, format }, read from state variables when the screen opens; a line whose variable does not exist is not shown |
buttons | list | ["retry", "menu", "credits"] | buttons in order, among retry, menu, credits, quit |
victoryTitle, defeatTitle | text { en, fr } | empty | heading; empty = the built-in text |
victoryText, defeatText | text { en, fr } | empty | message under the heading |
creditsTitle | text | empty | heading of the credits; empty = the project name |
credits | list | [] | sections { title, names[] }, scrolled in this order |
creditsSpeed | number | 1.5 | credits speed in lines per second (0.2 to 10) |
poweredBy | boolean | true | end the credits with a "Made with" line |
pauseGame | boolean | true | pause the game while the screen is open |
loadingLine | text | next | loading of asset.preload shown by the buttons: next, all or off |
Stat formats: int, number, time, money, percent, text.
Services, events, variables #
ui.endscreen(service):show(result, stats?)withvictory,defeator anything else for a plain end (false if a screen is already open or a hook cancelled it),hide(),credits(),back(),view(lang)(everything a presenter draws),press(control)(keyboard or gamepad control; answersnavigate,back,activate:<button>ornone),activate(id),navigate(delta),stats(lang),registerStats(capability),result(),elapsed(),loading(lang),attach().ui.endstats(capability): a kit that exposesendStats(lang)returning[{ id, label, value, format? }]and callsui.endscreen.registerStats("<capability>")gets its lines in the recap.endscreen.shown(event): the screen opened, payload{ result, time }.endscreen.screen(event): the screen changed, payload{ screen, from }(end,credits,none).endscreen.action(event): a button was activated, payload{ action, result }(resultis null when the credits were opened alone).- Variables:
endscreen.screen,endscreen.open,endscreen.result,endscreen.time,endscreen.focus. A kit that setsendscreen.titleandendscreen.textbefore the end replaces the heading and the message. - Listens to:
game.won,game.lost,game.phase,mission.completed,mission.failed,player.died,engine.flow.ended(won is a victory, lost a defeat, anything else a plain end),engine.flow.restarted,engine.scene.entered,save.loaded,asset.preload.progress,asset.preload.phase.
Hooks and modding #
- Hook
endscreen.show: payload{ result, trigger, mission, time };resultis mutable (victory,defeat,end) and the hook is cancellable.triggerisshowfor a call, else the topic of the event. Runs on the web and Rust hosts. - A mod may change
victoryEvents,defeatEvents,missions,onFinished,onDeath,showTime,stats,buttons, the titles and texts,creditsSpeed,pauseGameandloadingLine. The credits belong to the authors and are not moddable.
Engines #
Web, native, Godot, Unity and Unreal share the same model. Godot and Unity draw it in the style of their menu; Unreal uses a widget class you can replace with EndWidgetClass.
When it does not do what you expect #
- The screen never opens: no event of
victoryEventsordefeatEvents, no mission inmissionsand noshow()call reached it, or a tap ofendscreen.showcancelled it. - A stat is missing: its variable does not exist yet when the screen opens.
- Play again does nothing:
ui.menuis not installed. - The game keeps running behind the screen: nothing called
attachyet, orpauseGameisfalse.
Limits #
One screen at a time: show returns false while another is open. The recap only reads variables and the lines kits register.
Versions #
Kit 1.5.0 (adds loadingLine). Service ui.endscreen 1.2.0, capability ui.endstats 1.0.0.