Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

1347615 Posts in 61901 Topics- by 53552 Members - Latest Member: SweetieBun

September 22, 2018, 07:51:56 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsCommunityDevLogsReset Hard: A time-traveling puzzle game with co-op and competitive multiplayer
Pages: [1]
Print
Author Topic: Reset Hard: A time-traveling puzzle game with co-op and competitive multiplayer  (Read 377 times)
danShumway
Level 0
**


Quidquid latine dictum, altum videtur


View Profile WWW
« on: June 13, 2018, 08:01:31 PM »


"Teach yourself to time travel in ten minutes!"

Premise

Reset Hard (original announcement) is a top-down time-traveling puzzle game, taking inspiration from games like Monaco and Frozen Synapse. Players are placed in pseudo escape-rooms and are tasked with completing objectives to escape.

When players die, they reset to the start of a level (up to 5 minutes in the past). No physical time travel occurs, but the player can keep any information they've acquired such as passwords or the locations of other players. This is a fairly standard mechanic that other forms of media have already explored to a certain degree (think Minit or Edge of Tomorrow).


Here, a player uses time travel to collect two passwords. The green arrows show one-way doors. The player enters through a door, memorizes the passcode, and then resets so they can collect the next code. Once they've collected code 1 and 2, they can unlock the main door and exit.


Here, a player is tasked with collecting both limited-use physical keys (which will not be retained when they reset) and passcodes. By using strategic resets they can reuse physical keys to get at different passcodes.

Single player levels are used to introduce players to basic time traveling mechanics and to get them comfortable with the game's puzzle style. Multiplayer is where things get complicated.

When a player resets, their position on the timeline changes but other players continue traveling through time as if nothing had happened. This means that players can occupy different points on the timeline. A player in the past can use their knowledge of previous events to get different vantage points or exploit choices that other players made.

If a player's actions in the past would require another player to make a choice, that player will get pulled back to resolve the choice. For example, let's say you shot me with a gun and I traveled back in time and unloaded that gun. When your past avatar tried to shoot me again, the outcome would be different. This would require you to take control of that avatar again, so you would get pulled back in time to resolve the situation.

Pushing and pulling other players (and yourself) backwards and forwards in time is essential for solving puzzles and getting the jump on competitors. You'll need to think of time as a manipulable, continuous 3rd dimension.


Technical Details

I'm developing Reset Hard using web technologies and NodeJS. This is in part to make it very easy for people to set up their own servers, mods, etc...  I don't plan to centrally host anything, I suspect that Reset Hard will be a much better experience via local multiplayer, so it's important to me that you be able to set up a LAN party without requiring participants to install anything. The game controls will be touch friendly and I will likely try to create an official mobile version.

I'm also targeting the web because I want to experiment with Open Source design. This is kind of a pet project that I've been interested in for a while, and Reset Hard is a nice, small, iterative project that's serving as a good subject to experiment with. To that end  I'll be building out tools to make it easy to mess with the game's internals and mod things.

The game mechanics are very close to what is actually programmed. I don't have a lot of abstractions, so for the most part there's no trickery - mechanics are all internally consistent, unit-tested, etc... I even use many of the same naming schemes in code. A timeline is a collection of frames, and players and objects that move through it are given keyframes. Mechanics are all completely deterministic, which enable me to do some nifty compression tricks, but for the most part none of them have been necessary.

Most of the game's logic, including lobbies, player progress, etc... is coded using the same timeline system - you'll be able to reset and solve small meta-puzzles within the main lobby, which should provide a nice playground outside of the official levels. I'm putting a lot of effort into making sure that there are no 'mechanical plot holes', for lack of a better term.

Reset Hard is a game about understanding systems, so there will never a point where a player asks "why did X happen?" and the answer is "don't think about it."
« Last Edit: July 02, 2018, 03:46:15 AM by danShumway » Logged

bombjack
Level 3
***


That's me :)


View Profile
« Reply #1 on: June 14, 2018, 12:13:21 AM »

the concept looks promising
Logged

danShumway
Level 0
**


Quidquid latine dictum, altum videtur


View Profile WWW
« Reply #2 on: June 25, 2018, 03:20:54 PM »

Sorry I haven't posted in a while, I've been mostly working on backend logic around the timeline and data streaming, and I felt like most of it wouldn't make for a very interesting post until I had something graphical.

One thing that might be interesting though is how I'm using CSS/HTML to build the interface. I'm working on Reset Hard as a one-person team with a fairly limited budget. That means wherever possible, I'm trying to find ways where I can do something once and adapt it to many different situations.

CSS/HTML menus are great for this. I do all of my development on a desktop PC, but I often serve Reset Hard as a webpage and demo it on mobile devices. This cuts down on the amount of hardware I need to drag around when I'm demoing the game in casual settings, since people can use my phone/tablet or even their own phones to connect to the game.




Font Scaling

With a more traditionally laid out interface where I used pixels to position everything, it would be very time consuming to target all of these devices. Instead, I use standard responsive design practices from the web like breakpoints so that I can design the interface once and adapt it to a wide variety of devices. The first way I do that is by using hdpi-friendly units like `rem` instead of pixels.

Code:
.message {
    box-sizing: border-box;
    margin-bottom: 3rem;
    text-align: center;
    font-size: 2rem;

    position: absolute;
    width: 100%;
    bottom: 0;
}

`em` and `rem` units are often under-utilized in software. What they allow you to do is define lengths in terms of font size. This is important because your font size will likely change when you switch between a tablet, PC, and mobile layout. If you use pixels, you'll need to adjust your entire layout whenever the font changes. If you use more responsive units, you can be pretty certain that margins, line lengths, and dialog widths are going to look good no matter what.

This also allows me to give users more choices around font sizes. Font size can be a major barrier of entry for players with poor vision. Where possible, I plan to make font sizes adjustable, and to possibly even include options to enable dyslexic friendly fonts. There's no way I'd have time to do that if I had to handle all of the math around resizing myself rather than just relying on the browser engine.

Grid-based positioning

I'm also making heavy use of CSS Grid to help with layout. CSS Grid is a huge improvement over previous web layout techniques. If your reaction to all of this is "gah, CSS would be a nightmare to use", check Grid out. You may be pleasantly surprised.

Code:
.interface {
    display: grid;

    background-color: #0b0b0b;
    grid-template-columns: [left] min-content [middle] auto [right] min-content;
    grid-template-rows: [top] min-content [middle] auto [bottom] min-content;
}

.interface[data-mode="loading"] {

    /* Expand to fill the full screen */
    .component-loading {
        grid-column: left / -1;
        grid-row: top / -1;
    }
}

Grid allows me to quickly lay out a lot of complicated display logic. I can say "put the user's inventory on the left-hand side of the screen, and take up *only* as much space as is necessary given the user's font choices. Then, display a map on the remainder of the available space."

If I want to switch the inventory to the right side of the screen, doing so is only one line of code:

Code:
/* old version: grid-column: left; */
grid-column: right;

This allows me to very rapidly iterate on my interface and to quickly switch between layouts while testing. It also allows me to expose more options to the player. I will likely allow players in the final game to choose between several different interface layouts depending on their own preferences.

Separating display code and logic code

A big mistake I used to make when I programmed games was tightly coupling my rendering logic with my application logic. For Reset Hard, I've completely divorced the interface from the backend. I use a couple of different methods to make this easier, but the end result is that the game state is represented entirely as serializable JSON. Within the rendering client, I have a global "display" state where I attach data. Whenever that data changes from any source, the display is updated. The state generation and the state rendering are completely isolated from each other.

For example, here is how I put up a loading screen.

Code:
display.mode = 'loading';
display.loading = {
    message : 'Now Loading Your Level'
};

Why have the display code so isolated? Two reasons: First, it allows me to keep my application logic untouched even when I'm overhauling or changing large parts of my interface. I'm iterating on Reset Hard fairly quickly, and if I had to worry about the effects of changing something in the interface on the rest of my logic, my development speed would be much slower.

Secondly, it makes testing *much* easier; I can load up my interface, pass in raw data, and do debugging without even running the game. For example, here's the entire backend code I might use when testing how a player sprite renders.

Code:
display.mode = 'level';
display.world = {
    entities: {
        "12": {
            "id": "178",
            "type": "player",
            "controller": "1529722005410",
            "x": 0,
            "y": 0,
            "collision": [
                {
                    "left": -10,
                    "right": 10,
                    "top": -10,
                    "bottom": 10
                }
            ],
            "message": null,
            "message_timer": 0
        }
    }
};

I don't even have to run the game if I want to tweak or test how the interface looks. If I have an odd rendering artifact that I want to debug, I can force the game to render just that artifact, and I can refresh and reload the rendering code without navigating through a bunch of menus or waiting for the game to start.

TLDR

I've had so much success using web technologies to make interface development easier that I suspect in the future I'll start embedding web views even into non-web, native games that are using lower-level languages like C# or C++. It's really sped up my development and debugging, so if you hate building menus and interfaces, consider looking into it.
« Last Edit: June 25, 2018, 03:41:49 PM by latinforimagination » Logged

danShumway
Level 0
**


Quidquid latine dictum, altum videtur


View Profile WWW
« Reply #3 on: June 27, 2018, 07:13:10 PM »

Update:

Over the past two days I've been working on collision detection and doing some narrative work.

Collision detection has been kind of a big wall to smash through; I did tons of it back when I used to program in college, so I assumed that I'd be able to knock it out in maybe half a day. However, nearly 4 years after college it turns out I'm pretty rusty on a number of the data structures that used to be second nature.

In Reset Hard, everything uses basic bounding boxes. This simplifies collision quite a bit - I don't need to worry about things like rotation or complicated intersections. Rooms and environments are tile-based, which similarly allows me to get some good performance benefits since I can calculate tile collisions in O(1) time. I use the same collision detection for both obstacles and triggers.

On the narrative side of things, the world of Reset Hard is starting to take shape. It's not a narratively heavy game, but there is a certain style and internal consistency to the world. I'm still trying to 100% focus in on what the story is fundamentally about - how to convert the gameplay ideas of experimentation and subversion into a world that has the same kind of playful feel. I'll likely do a longer post about this in the future.
« Last Edit: June 27, 2018, 07:18:48 PM by latinforimagination » Logged

danShumway
Level 0
**


Quidquid latine dictum, altum videtur


View Profile WWW
« Reply #4 on: June 28, 2018, 08:26:49 PM »

Update:

Spent a day working on overall engine structure, making sure that browser clients can reconnect if the tab closes. I'm also doing some research on sandboxing for mods.

I'd like modders to be able to script and extend the game, build custom maps, etc... there are two ways I could handle client security. The first is to say, "be careful downloading mods" and leave it at that; in other words if the player downloads malware it's their own fault. This is what most games do.

I would prefer to say, "here's a way to install mods that sandboxes them so they can't access your filesystem or make network requests." VM2 looks very promising, but I'm still doing research to see if there are obvious holes and what the performance is.

It may end up being a combination of choice one and two: "install mods at your own risk, just like with every other game. However, I will try to sandbox things as best as I can just in case you're bad at avoiding malware."

Logged

danShumway
Level 0
**


Quidquid latine dictum, altum videtur


View Profile WWW
« Reply #5 on: June 30, 2018, 09:52:12 PM »

Update

Starting working on some pixel concept and logo art. I want to (where possible) be able to show people the game without relying on paragraphs of text. I also want to find a way to communicate the feel of the game beyond the mechanics. I'll be updating the initial post as I finish concept images. I'll post sprite work as regular updates.

On the programming side of things I've been working on the engine for doing collisions with tiled maps and triggers. I'd like to be able to start building playable puzzles soon.
Logged

Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic