MOBA - A community-made RPG built with LiveView

Hey folks,

For the past year I’ve been building a game as a side project to learn LiveView, and in preparation for ElixirConf decided to turn it open source so that it can serve as a starting point for everyone else who wishes to learn LiveView as well and wants to go beyond the simple counter demos that you usually find: https://github.com/pedromtavares/moba

The project is a working product and is currently deployed in production at https://browsermoba.com, so it’s a very hands-on learning experience. Regarding complexity, I was careful to keep the initial version simple enough that everyone can jump in regardless of their Elixir skill level and still have fun.

If this sounds interesting to you, feel free to comment on the issue at https://github.com/pedromtavares/moba/issues/90 to let me know you want to participate.

Have a great ElixirConf!

35 Likes

https://browsermoba.com/battles/290847
and so begins my new life as a pro MOBA streamer

2 Likes

@pedromtavares Great project.

Here is my first bug report:


Hope it helps. :smiling_imp:
1 Like

Haha perfect, thank you! A bit sad this is probably a JS problem, integrating with outside libs (in this case that provides the tooltip) is that tiny part of LiveView that is not that great.

Bright future ahead, my friend!

1 Like

Error in running priv/repo/seeds.exs

The database for Moba.Repo has already been created

12:42:42.439 [info]  Already up
[info] AppSignal disabled.
[debug] QUERY ERROR db=2.9ms queue=0.7ms idle=450.3ms
INSERT INTO "users" ("email","email_confirmation_token","experience","is_admin","is_bot","is_guest","level","medal_count","password_hash","pvp_losses","pvp_points","pvp_score","pvp_wins","shard_count","tutorial_step","username","inserted_at","updated_at") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18) RETURNING "id" ["admin@browsermoba.com", "eae5887f-ae41-4989-811a-2a6f3c0c228c", 0, true, false, false, 20, 0, "$pbkdf2-sha512$100000$0Ktdi/cGImQ6VPJ03SKiTw==$ERZTfHgoHgfhZD1HjdekQdljHSZBt03e2aoAVWc3Z3t8Vyx9zx9p3EdZcmPHeeHpv1fusDPIgrHiYOyfFCPVJQ==", 0, 0, %{}, 0, 100, 0, "Admin", ~N[2020-09-03 04:42:43], ~N[2020-09-03 04:42:43]]
** (Ecto.InvalidChangesetError) could not perform insert because changeset is invalid.

Errors

    %{
      email: [
        {"has already been taken",
         [constraint: :unique, constraint_name: "users_email_index"]}
      ]
    }

Applied changes

    %{
      email: "admin@browsermoba.com",
      email_confirmation_token: "eae5887f-ae41-4989-811a-2a6f3c0c228c",
      experience: 0,
      is_admin: true,
      is_bot: false,
      is_guest: false,
      level: 20,
      medal_count: 0,
      password: "123456",
      password_hash: "$pbkdf2-sha512$100000$0Ktdi/cGImQ6VPJ03SKiTw==$ERZTfHgoHgfhZD1HjdekQdljHSZBt03e2aoAVWc3Z3t8Vyx9zx9p3EdZcmPHeeHpv1fusDPIgrHiYOyfFCPVJQ==",
      pvp_losses: 0,
      pvp_points: 0,
      pvp_score: %{},
      pvp_wins: 0,
      shard_count: 100,
      tutorial_step: 0,
      username: "Admin"
    }

Params

    %{
      "email" => "admin@browsermoba.com",
      "password" => "123456",
      "password_confirmation" => "123456",
      "username" => "Admin"
    }

Changeset

    #Ecto.Changeset<
      action: :insert,
      changes: %{
        email: "admin@browsermoba.com",
        email_confirmation_token: "eae5887f-ae41-4989-811a-2a6f3c0c228c",
        experience: 0,
        is_admin: true,
        is_bot: false,
        is_guest: false,
        level: 20,
        medal_count: 0,
        password: "123456",
        password_hash: "$pbkdf2-sha512$100000$0Ktdi/cGImQ6VPJ03SKiTw==$ERZTfHgoHgfhZD1HjdekQdljHSZBt03e2aoAVWc3Z3t8Vyx9zx9p3EdZcmPHeeHpv1fusDPIgrHiYOyfFCPVJQ==",
        pvp_losses: 0,
        pvp_points: 0,
        pvp_score: %{},
        pvp_wins: 0,
        shard_count: 100,
        tutorial_step: 0,
        username: "Admin"
      },
      errors: [
        email: {"has already been taken",
         [constraint: :unique, constraint_name: "users_email_index"]}
      ],
      data: #Moba.Accounts.Schema.User<>,
      valid?: false
    >

    (ecto 3.4.2) lib/ecto/repo/schema.ex:169: Ecto.Repo.Schema.insert!/4
    priv/repo/seeds.exs:55: (file)
    (elixir 1.10.4) lib/code.ex:926: Code.require_file/2
    (mix 1.10.4) lib/mix/tasks/run.ex:145: Mix.Tasks.Run.run/5
    (mix 1.10.4) lib/mix/tasks/run.ex:85: Mix.Tasks.Run.run/1
    (mix 1.10.4) lib/mix/task.ex:330: Mix.Task.run_task/3
    (mix 1.10.4) lib/mix/task.ex:364: Mix.Task.run_alias/3
    (mix 1.10.4) lib/mix/task.ex:292: Mix.Task.run/2
    (mix 1.10.4) lib/mix/cli.ex:82: Mix.CLI.run_task/2
    (elixir 1.10.4) lib/code.ex:926: Code.require_file/2

I don’t know why the line 53 through 55 is executed twice. A quick fix could be

...
|> Repo.insert!(on_conflict: :nothing)

And there’s an image priv/resources/lina.PNG, which should be priv/resources/lina.png, I believe.

I think you’re trying to seed it twice. Case you followed the instructions, mix ecto.setup already runs the seeds for you, so you don’t need to manually run it.

I’ve ran it again quite a few times here without issue and the Github CI also runs it on every push.

You’re right about the file, but it’s handled internally by Plug or Arc I think, did you encounter problems with it specifically?

Sorry, my fault. It’s the lina.PNG that triggered the second error, and when I fixed it, I accidentally ran the seeding without dropping the database first.

As a long time Dota fan, it’s nice to see a project combine those two interests! UI looks great and it was nice having an “interactive tutorial” to learn the basics of the game.

A thing I’m curious about: Do you have to worry about copyright problems? Or is it on purpose you don’t name your “artwork sources” because of that?

Hey Ilo,

Thanks! I’m a long time Dota fan as well, in fact it was the inspiration for the whole project.

It could definitely become a problem, however I was careful enough to separate the artwork from the project: none of the Dota artwork is being distributed, if you clone the project you get a bunch of generic icons that are freely licensed. So on the unlikelyhood of Valve ever finding this to be a problem (they are usually relaxed about community projects like these), I can simply replace all of the artwork in production in a couple of minutes.

Cool! I just pushed a rename to the lina.png asset, thanks for catching that!

@pedromtavares wow! so much polish and love has been put into this app. really enjoyed playing it.

and totally excited to dig into the source code. super fun project.

1 Like

Thank you, sir! Your kind words mean a lot, it’s been about 20 months in the making, so I’m glad you’re having fun!

Hope the code treats you right, highly recommend reading the full README before getting into it :slight_smile:

1 Like

Played for a bit looks really really good :icon_surprised: :star2:

I don’t know MOBAs but reminds me of longer slower paced games like neptunes pride.

Nicely done @pedromtavares!
Since LiveView’s release, I’ve been considering using it to rewrite some projects, mainly PBBG games I’ve built int the past. LV is such a good fit for this kind of application. Thanks for sharing your work with us, I’ll certainly take a look at it.

2 Likes

Really nice UI and thanks for sharing!

What’s about adding some translations capabalities so that it can be deployed in other languages than English without altering the source code?

1 Like

Thanks! The first iteration of this game was actually slower paced (like the one you mentioned, this was common for older browser games), with matches lasting for a week instead of a day, but after a few play tests I noticed that things got boring really fast and that a quicker game loop meant more replayability value, so after a few tries I finally landed on the current version.

After you get the basics of it you can essentially get the whole match done in about an hour (with the added benefit of pausing whenever you like), which, to me, is the optimal gaming session for when you just want to relax a bit clicking around.

Thanks man!

I think games are a great way to experiment with libs, especially considering that LV is not even on 1.0 yet, so it’s hard to justify using it on any business context (even though I think for internal use LV is already quite plausible), but with the more relaxed tone of games you can really get a solid grasp of the tech and still possibly get it under moderate usage load.

Hopefully you’ll find the project interesting enough to get involved :slight_smile:

Thank you! It was a great UX learning experience for me as it’s not my strongest skill, nice to see people are enjoying it.

Internationalization is definitely a good idea, in fact, I’m not an english speaking native so I would directly benefit from this to translate it to my language (brazillian portuguese). If this is something you’re interested in tackling I’d definitely encourage you to do so :slight_smile:

However, for the time being, I think you can get away with a Google translate on the entire page (if you use Chrome), it’s got quite smart in the past few years and certainly a good tool to take advantage of for being a web-based game.

2 Likes