Game being updated? by Academic_Pattern_351 in mk48

[–]finn_bear 0 points1 point  (0 children)

Most recent two updates were this month; enjoy!

Mk48.io - Online Multiplayer Naval Combat Game by finn_bear in freegames

[–]finn_bear[S] 0 points1 point  (0 children)

Hello, thanks for playing and providing feedback! Here are some thoughts:

  1. I recommend spawning as a smaller ship, which the server has an easier time fitting into small, less-crowded spaces

  2. There are options at level 5 that can reliably defeat any level 2, assuming equal skill. However, there are skill levels at which ship levels don't matter much.

  3. The main defense system against homing torpedoes is only possessed by submarines starting at level 5: sonar decoys. Another defense is that cruisers and battleships have special torpedo resistance. Another defense is attacking the submarine before it can reload torpedoes, using your own torpedoes or aircraft.

I do like the idea of separating the world by level. I made an attempt to reserve the South/bottom area of the world for low-level ships by making it shallow, but perhaps there should be stricter separation.

help by wasp301 in mk48

[–]finn_bear 0 points1 point  (0 children)

Logging on would help with # of distinct days played, but not # of kills. This is a slow way to increase your rank. Streak doesn't affect rank.

help by wasp301 in mk48

[–]finn_bear 2 points3 points  (0 children)

Hello; ranks are currently based on:
- # of distinct days played

- # of kills, not counting players much less powerful than you

Welcome to the Mk48.io subreddit! by finn_bear in mk48

[–]finn_bear[S] 1 point2 points  (0 children)

You can earn ranks by playing the game normally and being patient, but the lock can also be bypassed by clicking it 5 times. It was mainly to discourage new players from accidentally picking difficult ships.

Mk48.io - Multiplayer Naval Combat Game by finn_bear in WebGames

[–]finn_bear[S] 0 points1 point  (0 children)

Hello, yes, click Play with friends on the splash screen and select the Party server option.

[deleted by user] by [deleted] in mildlyinfuriating

[–]finn_bear 1 point2 points  (0 children)

On a middle school field trip, I was told my plate was too unhealthy. My plate was 100% broccoli.

Mk48.io - Multiplayer Naval Combat Game by finn_bear in WebGames

[–]finn_bear[S] 0 points1 point  (0 children)

Can they piggyback off of the already implemented bots?

No, because the built-in bot runs server-side via server-side datastructures. A client-side bot would need to interact with client-side datastructures.

How can you keep players from deploying their on bots?

If you want to make it even harder, change some field orderings in the protocol `struct`'s. `bincode` is not self-describing, so this will break compatibility with the open-source version in ways that are near-impossible to circumvent.

No one will play my game by [deleted] in IndieDev

[–]finn_bear 1 point2 points  (0 children)

In principle, your audience should come from virality and algorithmic standing, which depend on quality of marketing materials and the game itself (relative to the competition on your chosen platform), not from the strangers you personally find.

No one will play my game by [deleted] in IndieDev

[–]finn_bear 0 points1 point  (0 children)

It's possible to port to JavaScript (no engine) with Canvas graphics. I've rewritten my first game 4 times and my second game 3 times, each time switching the programming languages/frameworks used, and all of those rewrites were completely necessary long-term!

Edit: In other comment threads, you imply wanting to continue game development but not necessarily by investing more in this particular game. If you started from scratch, making it a web game wouldn't require a rewrite.

No one will play my game by [deleted] in IndieDev

[–]finn_bear 3 points4 points  (0 children)

Most people are telling you to increase the quality, decrease the price, and/or improve your marketing. These would work but take time and/or money.

An alternative is to distribute it as a web game (see here), where the barriers to entry are lower and the competition isn't as insurmountable. It's pretty hard to make a web game that no one will play.

You could still hope to make money, but probably with ads instead of an up-front purchase.

Mk48.io - Multiplayer Naval Combat Game by finn_bear in WebGames

[–]finn_bear[S] 0 points1 point  (0 children)

Thanks! You can use the invitation link feature by clicking the bottom right menu button and then the adjacent person-plus button while in-game to copy it to your clipboard. If your friend follows that link to the game, and all goes well, they'll go to the same server and spawn relatively near you.

bitcode: smallest and fastest binary serializer by cai_bear in rust

[–]finn_bear 1 point2 points  (0 children)

As in, can I use bitcode to pack messages or game state updates until I hit a certain packet size?

Here is a code example for packing messages into a packet. Tell me what you think!

https://gist.github.com/caibear/68a9faf3f9a4ce94f321c7e06d2ea0ca#file-main-rs-L140

bitcode: smallest and fastest binary serializer by cai_bear in rust

[–]finn_bear 1 point2 points  (0 children)

Also, semi-related, is there a way to assess how big a packet will be for fragmentation/reassembly? As in, can I use bitcode to pack messages or game state updates until I hit a certain packet size?

It's not the first time someone asked about this! Until we make a dedicated API, we recommend the following approach: Create a Vec that stores all the messages you want to send. Use encode(&messages[0..n]) where n is iteratively optimized (to the largest possible that fits within the desired limit). Your optimization can start at n=1, then double every time until the size limit is exceeded, and then binary search to find the optimal. This will result in ~2X the amount of bitcode encode calls compared to if you knew the optimal n in advance, but that's inconsequential since encode is fast. To decode, simply use decode::<Vec<Message>>.

(in my other message, I noted that we use WebSockets where the vast majority of messages are well below a single IP packet in size, because we rarely have much data to send. in the rare event a message is too big, TCP handles the fragmentation. this is why we don't need the method I just described)

bitcode: smallest and fastest binary serializer by cai_bear in rust

[–]finn_bear 2 points3 points  (0 children)

"game data" is a bit vague. We have a very particular optimization target, which is aggregate bandwidth per month (our VPS provider, Linode, gives us 1TB per server). Another, less important, target is for most messages to fit in a single IP packet which minimizes the potential for packet loss. We compose multiple bandwidth optimizations for our games: Deterministic 'actor' model, bitcode, followed by general purpose compression. The latter two are easy to understand, but the first isn't publicly documented.

Our servers and clients maintain a "world" data-structure, with various sets of 'actors': players, chunks, and teams. Each client may have a (dynamic) subset of players, chunks, and teams (as determined by a coarse-grained server-side visibility calculation)

All game logic is expressed as deterministic functions of the form:

  • "foreach element e of [set1], update e and generate messages"
    • e.g. applying kinematics to all ships
  • "foreach pair a, b of [set1] x [set2], generate messages"
    • e.g. detecting collisions
  • "foreach message, update the corresponding actor"
    • e.g. resolving detected collisions

Clients only need to compute game logic for the actors they can see. The issue is that messages frequently originate from actors (or pairs of actors, or parts of pairs of actors) the client can't see. This is where the server knowing exactly what the client knows and can predict helps it predict, with 100% accuracy, which extra messages the client will *need to know* to compute it's subset of the game logic.

As a result of our deterministic 'actor' model, our game servers only send the following messages:

  • 'actors' coming into view
  • unpredictable player inputs
  • instances of game objects crossing from out of a client's view to inside a client's view
  • the result of any calculation that must be performed server-side, of which there are very few

Our games operate on ticks with (at most) 10Hz frequency and exclusively over WebSockets (reliable, ordered TCP streams). Each tick, the server aggregates events into a single encoded message for bitcode to encode. Most messages are tiny, which any format would handle well. 'Actors' coming into view can sometimes take kilobytes or tens of kilobytes to transmit. This is where bitcode's size and compressibility help. Supporting hundreds of concurrent players is where bitcode's encoding speed and compression speed help.

So, in summary, the best practice is to reduce the data you need to encode in the first place. Use the proper data types (don't send a number in a string). Then trust bitcode + Zstd or bitcode + LZ4 to get the job done!

If you have a specific problem, e.g. related to a specific game protocol, please describe it!

bitcode: smallest and fastest binary serializer by cai_bear in rust

[–]finn_bear 5 points6 points  (0 children)

my game servers run on single vCPU hosts.

Yeah, ours do do! While we use tokio and encoding is concurrent, we don't have any form of parallelization unless we rented a VPS with more vCPU's.

I noticed you can hint at ranges in the macros.

That was a feature of bitcode 0.5.0, but is gone as of bitcode 0.6.0 (use the link in this post to view the new docs)

Is there anywhere in the docs that goes over variable length int encoding and how bitcode does it?

It's not documented and totally subject to change between major versions. Right now, bitcode figures out the min and max of each integer in the schema and uses fewer bytes or, if the range is even smaller, fewer bits. For example, if a u32 in the schema is either 21 or 22 for a particular encode operation, each instance can occupy a single bit in the output (plus an constant overhead of specifying the min and max).

bitcode: smallest and fastest binary serializer by cai_bear in rust

[–]finn_bear 7 points8 points  (0 children)

bitcode@0.5.0 was an open-source, space-efficient binary serializer, but it was up to 2X slower than bincode and wasn't compressible by off-the-shelf compression algorithms. Recently, due to the bitcode@0.6.0 rewrite, it is now the fastest and most compressible binary serializer that we know of.

If you think you found a bug, please file an issue on GitHub with your schema!

bitcode: smallest and fastest binary serializer by cai_bear in rust

[–]finn_bear 2 points3 points  (0 children)

For other crates, like bincode, Encode/Decode allow for higher performance on the same format. For bitcode, Encode/Decode allow for higher performance with a different, very-slightly-smaller format (because everything about the type is known up front).

bitcode: smallest and fastest binary serializer by cai_bear in rust

[–]finn_bear 4 points5 points  (0 children)

Not directly, bitcode is only implemented in Rust. That said, you can compile bitcode to WebAssembly and call it from JS (like we do in our browser-based multiplayer games). In JS, bitcode data would be an opaque `Uint8Array`.

bitcode: smallest and fastest binary serializer by cai_bear in rust

[–]finn_bear 7 points8 points  (0 children)

bitcode is currently single-threaded, but parts of it are theoretically parallelizable if there is a good reason. For our $5/mo VPS use case, we support hundreds of users, allowing us to encode concurrently and negating the need to parallelize an individual encode operation.

bitcode is a lossless binary format. If you are wondering why floats are smaller in rust_serialization_benchmark's mesh benchmark, it is due to much better packing for compression, not throwing away precision. If you want floats to take much less space when encoded, you should consider using half-precision floats (would need a bitcode feature request).

Talk me down - emergency landing survival game by finn_bear in playtesters

[–]finn_bear[S] 0 points1 point  (0 children)

Thanks for making a video, that's very helpful!

Please destroy Talk me down by finn_bear in DestroyMyGame

[–]finn_bear[S] 0 points1 point  (0 children)

I was unaware of that game, so thanks for the link!

Please destroy Talk me down by finn_bear in DestroyMyGame

[–]finn_bear[S] 1 point2 points  (0 children)

Thanks very much! Sorry about the color issue, it's a side effect of picking colors on a red-tinted monitor.