Giter Club home page Giter Club logo

bomberman-of-the-hill's People

Contributors

bschwind avatar golddranks avatar joukokar avatar pablomansanet avatar skywhale avatar strohel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

bomberman-of-the-hill's Issues

Player action logic

Business logic for the effects that player actions have on the world, as well as designing the Action enum itself.

Movement

Movement action should, well, move the character, but it may have non-obvious edge cases:

  • What happens when a character walks into a bomb? In some bomberman games the bomb is pushed and starts sliding (though this is often with a powerup). We can assume the bomb is immobile for the MVP most likely.
  • What happens when a character walks into a location that another character is moving to? How is this resolved? (it would be ideal if we could avoid solving it arbitrarily, such as through iteration order. An idea could be to just visually "bump" them and return them to their original position).

Placing bombs

  • Where is the bomb placed? In most bomberman games, the bomb is placed exactly under you, which causes a bit of an exceptional state as it's the only "normal" way you can share position with a bomb. As soon as you move away from the bomb, you are unable to occupy the same tile again. I don't see a reason we can't do that ourselves, though it means we'll have to accomodate for this in the "tile" enum passed to the player (i.e. Tile::EmptyFloor(Some(player), Some(bomb))).
  • What happens when the player tries to place a bomb and is unable to? (bomb limit). Animating the failure, even if it's just a little bomb with a red cross on top of their head, could do a lot for people to visually "debug" what they did wrong.

Bomb chain reactions

If bomb's blast touches another ticking bomb, it should detonate immediately regardless of its fuse.

Q: Shall we detonate the "secondary" bomb in the very same tick, or perhaps in the next one?

Music + Game Audio

Assuming we're going to want audio (though I'm not sure how the final setup will work, during the meetup).

Music

  • As with #4, is copyright a problem? If not, do we take straight from bomberman or go for something different?
  • Audio support in bevy is pretty basic, though I can't imagine this being a huge problem for a game like this. If it turned out to be an issue, there are other audio integrations for bevy out there.

Sound effects

  • We'll need sound effects for the basic stuff: explosions, powerup pickups, deaths, round countdown...?
  • We may want sound effects for players joining and "brain swaps".

WASM actor upload system

At the moment, the number of live players is equal to the number of valid .wasm player files under crates/bomber_game/assets/players. For the meetup, we want a system that makes it easy for attendees to upload their compiled players and see them reflected on the game field immediately.

How it would be used

  • It would be amazing if we could make it part of build.rs so an attendee only needs to run cargo build on their player crate and have the build script pick up the output and stream it to the right port. Unfortunately build.rs can do pre-build steps but not really post-build steps as far as I know, so the only ways I can think of making this happen would be a bit hacky.
  • An alternative could be to come up with a custom cargo command, so that attendees can call cargo upload-player, which will in turn build the crate for the wasm target and upload the resulting .wasm file in one go.

Server side

  • An option could be to have a bevy system (using one of the network plugins) just picking up connections to a TCP socket and streaming the bytes directly into .wasm files. This would then be picked up by the folder watcher, and we'd have a way to mix uploaded players and players we manually "drag and drop" into the server.
  • Alternatively we could get rid of the folder watching altogether, and have it so the networked bevy system directly builds the wasm asset from the TCP stream. This would be cleaner but lose the benefit of the "drag and drop" option.

Concerns

  • Ideally attendees will have only one hero at any given time, so we have to come up with a robust way of identifying which .wasm upload belongs to which attendee. We could pin it to IP addresses, or request attendees to implement a player_name() method in the player trait so that we can decide at runtime whether they are a duplicate.

Game rendering

Assuming we have all the necessary sprites from #4.

  • Pure sprites, or do we want any particle effects or custom shaders?
  • What surface(s) is this meant to be rendered on? I'm imagining a big screen.
  • Given the above, will resolution be a problem? We might need pixel-perfect rendering, and there's a good discussion here

Misc gameplay improvements

There are a few tidbits that I've realized while testing the current demo (since it has very recently become fully "playable"). These aren't new features per se, but quick changes that could potentially improve the gameplay experience for the MVP we drafted.

  • Bombs explode a bit too fast for the current character move speeds, so it's probably best to increase the fuse timing so players aren't forced to take the immediate next turn into a corridor.
  • A typical bomberman action is missing: Placing a bomb while moving! I'm thinking of adding one entry to Action with DropBombWhileMoving(Direction). Without this, people won't be able to create the classic bomb chains, which we totally need ;).
  • Bomb limits are missing, which I think are important regardless of whether we have time to make powerups happen. An initial limit of two or three simultaneous bombs seems okay.
  • I feel like the character sight range should be higher by default. It's currently 3 tiles, which is barely enough to spot a bomb. Bumping it up to 5 should be good for now.

Assigning myself to this as these are quick, easy wins which will work well for the rest of my week, since I will be busier. If anyone comes up with other improvements to make, post them here and I'll add them to the list.

World upkeep logic

I imagine the game will roughly proceed in alternating phases, spaced by an even number of frames:

  • A phase where all players decide and commit their actions, and these actions take effect on the world.
  • A phase where all passive world effects trigger (bombs ticking down or exploding, points being granted, etc).

We'll need bevy systems to perform all of these "world upkeep" tasks. Some examples:

  • Ticking down the bombs and/or exploding them.
  • Increasing the point value of players on the hill.
  • Cleaning up dead players, adjusting their point scores, and respawning them.
  • Removing the breakable tiles that got hit by an explosion.

Queueing/many player support mini-RFC

The problem

With the resolution we're aiming for and the map size that we have, there's a clear limit to the number of players that can compete on the same arena. From my initial testing, I'd say 12 simultaneous players is about as far as we can go before we run out of breathing room. 8 would be ideal.

We want more than 8-12 players to participate, especially after deciding we want to open the event to outside participants and stream it on twitch, so we need to find a way to have everyone play for a fair amount of time and keep them engaged.

A queue system proposal.

I propose we rework the file upload/file handle systems to behave under a simple set of rules:

  • If the current game has fewer than MAX players, simply add the players to the current arena.
  • Players that die should continue to respawn indefinitely in the current round, taking priority over the queue. This is important not to discourage inexperienced devs by pushing them to the back of the queue after an unfortunate death. The penalty for dying should be losing points, not losing the opportunity to play!
  • When a player tries to join a full match, they're instead added to the global queue.
  • When a match ends, all players on it get pushed to the back of the queue, and the next set of MAX players get added to the next round.
  • Players should be encouraged to re-upload their wasm blobs as much as they like, so reuploading should not affect position in the queue. Reuploading should not even despawn the character: The AI change will happen live.
  • When a player is inactive (no new uploads) for a long time and their character has played enough rounds, it will be removed from the queue (this is just to prevent idlers that left the twitch steam long ago from taking space).

There's a couple implicit principles in the proposal that I think we should maintain even if the implementation particulars change:

  • When a character starts playing, they should always get five minutes of play. This is why I think it's better to throw in a new set of challengers every round, instead of constantly churning them in the same round every time someone dies.
  • People should felt encouraged to experiment. Knowing that your character will stay in the round no matter how badly you do will make people less scared to try crazy things.

An illustrated example

For the example, I'm going to assume that MAX = 4 (the number of players that can play at the same time in an arena) and that players are named alphabetically from A to Z.

  • The first round starts, and the game field is empty. 3 minutes pass as people fiddle with the logic.
  • Players A, B, C, D join, and they appear in the arena.
  • Players E and F join, and the queue is now [E, F] . Those players are notified of their position somehow.
  • Player A dies and respawns, but the queue situation is unaffected.
  • Players E and C decide to reupload their AI. C continues playing normally without respawning, and E's position in the queue is unaffected.
  • The round ends and all players in it are pushed to the back of the queue, which is now [E, F, A, B, C, D].
  • The next round starts, with players [E, F, A, B].
  • Player G joins, and the queue is now [C, D, G].
  • ...etc

As always, open to thoughts, suggestions. implementation concerns, etc :) I'm also unsure how much of this process we want to represent in the UI. Maybe some sort of message signaling who's playing the next round could be fun!

Game rules (Open question)

Which game rules (from bomberman or otherwise) are we going to implement?

General principles

  • Players can join asynchronously at any time by uploading their latest actor version.
  • If we are to have rounds, joining late is not penalized (in other words, the reward for joining late but with an accurate strategy should be higher than joining early with a poor one).
  • Should be easy to parse visually without heavy rules explanations. Anything that isn't obvious should become obvious when reading the Player trait to implement.

Discrete movement?

We seemed to roughly agree that discrete movement would work well. Some thoughts on how it could work:

  • Increase the frequency of the "universal tick" but make players capable of acting at certain tick intervals depending on their move speeds (e.g. a default bomber would act each 10 ticks, one with multiple boot powerups each 6).
  • We need to think of how to resolve moves for cases where two incompatible moves happen simultaneously (e.g. two players moving to the same tile). It would be best not to rely on arbitrary iteration order.

Tiles

What tiles do we want?

Obvious ones:

  • Walls, floors, bombs, players, crates (i.e. breakable terrain)

Optional or not so obvious ones:

  • Powerups (might be redundant with the "shop" idea, but bomberman is very fun with powerups!) Here's the canonical list from the bomberman wiki.
  • Hazards (lava, spikes, etc?) Only makes sense if players can be moved against their will or if the hazards can appear under them (maybe telegraphed/with a timer...)
  • Switches that make hazards, powerups, bombs etc spawn.
  • "Hill" terrain (i.e. the terrain you're meant to hold to gain points).

Scoring

How do we score the game?

Hill points + powerup bounty idea

  • Players/teams gain points per second they spend in the hill. If they leave the hill or die, all points are lost. Also, a good number of their powerups (maybe all?) get spread around their point of death. Every X minutes the round closes, the winner is declared and the map rotates. This way people joining the round late can still win if they manage to be the last one standing in the hill.
  • Dead players wouldn't need to be removed from the game; they could just respawn at a free corner and keep playing until they choose to replace their algorithm.
  • Question: Should replacing the algorithm be allowed while the character is still alive, or should it be put on hold until death or the next round? If it's allowed, could it happen immediately? It's a silly worry but I wonder if crafty players would think of live-swapping their bomberman brain to manually control the character! (though this would make for an interesting story and make a good argument for Wasm performance). It's tempting to leave it "exploitable" to see if someone is crazy enough to build a virtual controller where each keypress uploads a new algorithm :)

Rounds

Do we want rounds at all? Some thoughts:

  • Rounds could be an interesting way to give some closure and rotate the maps, while still keeping the asynchronous join system.
  • Competitive bomberman usually starts with a bunch of crates/obstacles blocking the way, so it would be good to have rounds if nothing else to change the pace.

Actor interface

What "window" into the world do we give the actors? How much can they see? What can they do?

  • One way to do it would be to have all actions be worth certain number of ticks, so everything takes a bit of time, for example:
    • Inspecting a single adjacent tile is free (future calls to the inspect function would return None or error out, during the same turn).
    • Inspecting all your adjacent tiles takes 1 tick (if we want to be fancy we could animate bomberman just looking around).
    • Looking at an entire row/file in front of you takes 2 ticks.
  • If we implement the above, I'm not exactly sure how the API would look. You probably wouldn't have an inspect method, but rather a more expressive Action return type with more variants than just movement, and a way to retrieve the result of your last action (so for example if you return Action::Look(North), the next turn you'd enter your act method with an ActionResult::Look(Tile) passed to you. If you return Action::Move(East) your next turn would happen later, and you'd get an ActionResult::Move(EmptyTile)).
  • Alternatively, we can keep it roughly as it is and have wasm imports you can call through the World API to inspect your surroundings, and do it as many times as you want during your turn, but have your next turn take longer to happen if you've done too much (go into "tick debt" as it were).

Webassembly module metering

We need to ensure that broken wasm modules don't hinder the game's progress.

  • Time out players that take too long and remove or rename their wasm files.
  • Ensure players that time out or panic are removed from the handle list (deleted or renamed wasm files), since at the moment a crashing player is repeteadly spawned causing a large performance hit.

Game UI

How much UI do we actually need?

Essentials:

  • Round timer
  • Name tags on top of players
  • Player score trackers (probably on the side not to clutter the screen too much)
  • Player powerup trackers

Optional stuff:

  • Map name + next map name (for people to prepare)
  • Some form of event logger (e.g. "Team XXX's bomber has entered the battle!")

Do we use the Bevy native UI?

  • It's a bit unwieldy and one of the pain points of Bevy as of 0.5, but it's also well documented in the examples.
  • An alternative could be the egui integration, which is super comfortable to use, but hard to make it look pretty (is this a problem?)
  • A particular problem I stumbled on was making text live in the world space (as opposed to the UI space) in order to track game elements. This was notoriously difficult back then so I'm hoping it has gotten better.

Improve map generation and representation, develop the tile system.

At the moment, the tile system in the demo is very basic.

Expand ASCII map parsing

  • Add more tiles and their associated ASCII characters to represent the current MVP.
  • Add spawn point markers to the ASCII representation.
  • Add a bevy system to choose the maps to be changed between rounds.

Map representation

Currently, the map is an immutable, Arc wrapped structure to deal with the limitations of wasm callbacks, and game objects such as the character and death marker don't reside in the map at all, but are simply rendered on top of it. This wasm limitation will be gone, so we don't have to worry about Arc to share references with the wasm instances.

Some thoughts:

  • To be idiomatic in an ECS system we likely don't want the map to be a big struct that literally contains the game elements. Instead renderable elements will be represented by entities containing some kind of WorldLocation component.
  • When passing the "surroundings" to a character's wasm module, we'll probably have to change abstractions a bit and pass Tile enums to the character which may contain things in them, e.g. Tile::Wall, Tile::Floor(None), Tile::Floor(Some(Bomb(countdown: 2))). So we need a bevy system/function that iterates over all things with WorldLocation and works out the configuration of these enums to pass to the character.

Helpful crates

There are crates out there designed for this sort of situation that may help us, bevy_tilemap is the original one I looked at, though I see bevy_ecs_tilemap helps representing tiles in a more ECS idiomatic way so it may be worth looking into as well.

Scoring, round and victory logic

We'll need systems to keep track of player score, count down the game time, and switch game state to a victory screen at the end of a round, then scheduling a new one.

  • Bevy supports states since the latest version, which help organizing the transition between rounds and to/from a victory screen.

Gather/make basic spritework

I'm assuming 2D rendering, so we'll need some sprites :). I don't know exactly how this will be rendered in the November meetup so I'll leave it to you to define the requirements.

  • Is copyright a problem? I imagine it's not an issue for a fun meetup project, but I'm not a lawyer so asking just in case.
  • Do we want animation? There should be plenty of bomberman sprite sheets around, but not sure how complicated we want to get here.

Improve the .wasm glue code layer

At the moment the shims around the Player trait are a bit rough, and it could be a big win to automate as much of the process as possible (within reason) so we don't waste a lot of time keeping the glue code up to date manually as the Player<->World interaction changes.

Some pointers:

  • This blog post series, even though it uses wasmer instead of wasmtime, remains the best reference I've found since he's trying to solve a problem almost identical to ours.
  • Wasmtime supports a much better way of managing imports and exports to what's currently in the codebase, using a Linker. Doing this properly would also solve some annoying panics I found while testing (for example a Player module that doesn't actually look into the result of inspect at all would cause the import symbol not to be emitted, which would currently cause a panic as our spawn_player function expects exactly one import).
  • It would be good to think early of some basic form of metering, to handle the case where someone uploads a loop hero (of the loop {} kind) and stalls the entire process.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.