dfinity / motoko

Simple high-level language for writing Internet Computer canisters
Apache License 2.0
517 stars 97 forks source link

Mini Application: (Agar clone) clone, in Motoko #1345

Closed matthewhammer closed 4 years ago

matthewhammer commented 4 years ago

As an application that will test the language (and platform), this issue suggests cloning this (javascript clone) of Agar.io, but using Motoko and the Internet Computer instead of a traditional central web server:

https://github.com/huytd/agar.io-clone

Benefits:

chenyan-dfinity commented 4 years ago

the clients and server share state, but compute independently

This is interesting. Does it mean we implement the computation twice, or we have a way to mechanically generate client code? Also, Motoko doesn't have a shared memory location in wasm. How do we define shared state?

ggreif commented 4 years ago

How do we define shared state?

https://wiki.c2.com/?HalfObjectPlusProtocol ?

matthewhammer commented 4 years ago

Does it mean we implement the computation twice

Unfortunately, I think that's pretty much unavoidable, and that's partly why I've been so keen on the idea of running Motoko client-side, in the browser, someday.

I'm afraid I don't follow the shared memory location issue. What solution does this prevent?

In the short term, I suggest we do it "brute force" and just write both client and server separately, manually. For this particular game, the client and server are each very simple, and it shouldn't be too hard to do the work twice, even for a very small team.

chenyan-dfinity commented 4 years ago

Unfortunately, I think that's pretty much unavoidable, and that's partly why I've been so keen on the idea of running Motoko client-side, in the browser, someday.

This seems to be a problem for all online games. Are they all implementing these twice? How to detect cheating if I write my own client code that diverges from server? I wonder if we can make use of query calls similar to Logo: Commit a state change, before the commit finishes, use query calls to buffer the state locally. Then make another commit once the previous commit is done.

shared memory location

You mentioned real-time. That makes me think we need a shared memory location between wasm and the browser. The state is directly accessible from the client without even need to make a query call. We can do this in Rust, but not in Motoko.

matthewhammer commented 4 years ago

Are they all implementing these twice?

Not sure about web games, but I can speak with some authoritatively about Quake II, which ran the same physics C code in both places (client side and server side). If modern web games are similar, I think that they have to implement the physics twice, or do it once and have it run similarly on both the client and the server. If they fail to do this right, or cut any important corners, people can hack their client and cheat.

In the world of web games and in the case of Quake II, they can avoid the pain by just using a common client/server language: JS for web games, and C in the case of PC games.

For us, we can't do that now, sadly (unless we just use Rust everywhere? Still I'd rather use Motoko someday for that purpose).

I wonder if we can make use of query calls similar to Logo: Commit a state change, before the commit finishes, use query calls to buffer the state locally. Then make another commit once the previous commit is done.

Since Motoko only runs on the backend, and since we don't generally want to implement the physics twice, in two languages, your idea of using query calls to avoid this in the short term is interesting to me as well, and definitely seems worth exploring more.

a shared memory location between wasm and the browser

Ah, I follow now, thanks. Admittedly, I don't have a clear idea of how the game client Wasm (from Motoko someday) and the browser would interact in general. Hopefully they'd have a way to talk really fast somehow.

In particular, it'd be nice if there was an alterntative "system interface" for Motoko (not the IC one) that represented a browser similarly to how web_sys exposes one to Wasm that comes from Rust. As you know, there's a lot of web_sys that, like the IC system, is event-based. My use of it in Rust to make graphics in the browser worked this way. It seems like it could become a natural fit for the (single-threaded) Motoko actor model, if we choose to evolve Motoko as such. I recall this coming up at a Languages team meeting after one of our toy demos.

chenyan-dfinity commented 4 years ago

there's a lot of web_sys that, like the IC system, is event-based.

For Rust, you don't even need web_sys. You can define a static region:

#[no_mangle]
static mut BUFFER: [u32; N] = [0; N];

Then Javascript can access it directly: const buffer_address = wasm_instance.exports.BUFFER.value;

nomeata commented 4 years ago

Kinda stale, not sure if anyone still cares, so closing.