Defold Eva - Overview

Intro

I would like to introduce my Defold-Eva framework to you :tada:. The first commit was made in September 2019, and there are almost 500 commits in my repository so far (for comparison, Druid has over 600 commits).

As you can see, it is quite a long and large project! The repository has always been public, and many people have asked me about it, whether I plan to publish it or promote it in the community. However, because it is a fairly large project, it is difficult to just hand it over and say, “use it”. Yes, it has a readme, documentation, and annotations for EmmyLua, but it is still not very easy to explain how to use it clearly :upside_down_face:

I decided to publish it and briefly explain what it is and how it works, what you can look at, and what you can learn from it. I think it will be difficult to use it in its entirety (I have used Eva in many projects and prototypes, I think there will be about 7+ of them), but it will be useful and interesting for you to see what and how I do things.

So, Eva is a set of modules that are united into one system. It is not necessary to use all of them, only the necessary set in each specific case. Most of them are not directly related to the game (although there are also things for gameplay). There are about 40 modules here, from system ones for working with protobuf and data saving, to things like a quest system, game offers and game mailbox. Full list of modules you can see here.

Most things work, documented, and covered by tests. But there are also things that I haven’t finished or haven’t finished yet, but they are still there and can be looked at.

Also, Eva can be connected with my other libraries, some of which may not be announced. For example, Sheets-Exporter and Detiled (the name is awesome, isn’t?).

It’s time to finish the introduction and briefly go through the modules and see what’s here!


Just a GIF to spice up the text. Animated in Panthera.

Disclaimer

Eva is not documented well, some functions can be broken. Eva is in development, so API can be changed in future versions.

I share it in educational purposes, so you can see how I do different things and use it in your own projects. I will be glad if you will use it in your projects, but I can’t guarantee that it will work well.

Defold-Eva

Eva - basic Defold framework, designed for games with meta game. It provides a lot of additional API and systems for easier game development, liveops and analytics. It contains a lot of different modules, which can be used separately.

The API list is really huge, you can check it here: Eva API

Feature list:

  • Use protobuf for data and user profile validation, default values and marshaling

  • Rich utility API for different actions

  • Quests, festivals, offers, daily bonus and other systems embedded

  • General event system with already defined 50+ events

  • Tiled support with 3 different grids support + pathfinding

  • Single input module to manage all input (in GO space)

  • Data management with Google Docs and Sheets-Exporter

  • Customize Eva modules with single settings file

  • Game time protection: use local, uptime or server time

  • Tokens memory protection: protect from memory scanning

  • Monetization (iaps and ads) rich support

  • Eva log system and errors caching for analytics

  • Customizable modules with your own code (window, quests, trucks, etc)

  • User profile migrations

  • Eva render with customizable post-effects

  • Invoices support: send delayed rewards, mails or time-restricted stuff to the player

  • Push support with snooze hours, push count restrictions per day

  • Included luax module with extended functions

  • Debug functional for easier development included (save slots, reset profiles, game restart, etc)

Full README here

Eva Modules

I suggest taking a brief look at several modules that might be of interest to you. Most of the modules are contained in one file, and you will be able to understand most of them.

Ads Module

In my ads module implemented two system adapters - Unity and Yandex. Which one to use is set in the general settings. Here, you can see what the adapter looks like.

In the ads settings, you can configure how often a particular placement can be launched, what time breaks between them, how much time until the next ad, and the ability to show the ad and immediately pass a callback for a successful display.

IAPs Module

In general, the in-game purchases module doesn’t contain anything “unusual”, but the most interesting thing is fake transactions that allow you to test all purchases in the game before connecting any payment system and configuring products. For this purpose, “fake” transaction data will be generated, and all information about purchased items will be saved in the profile.

Lang Module

I really like the method names for obtaining localizations in this module. I borrowed it from @AGulev a little bit :wink:

Here are three methods described there:

  • txt (short for text) - get text by key

  • txp (short for text_params) - get text by key and substitute parameters into it

  • txr (short for text_random) - get random text from an array by key

Why are the parameters from a to g instead of ...? There were some problems when the ... parameter was passed incorrectly through several functions, which caused very strange problems in some places. In the end, it was necessary to abandon this and do it in this way.

Proto Module

This is a simple module of a hundred lines that can quickly explain how to work with protobuf. There is also a cool function that checks the table for compliance with the protobuf schema, adding default values or removing data that is not in the schema.

This allows some user profile migrations to be performed without any unnecessary code.

Quests Module

The entire flexible (in my opinion) quest system in one file! Quests can have start conditions (other quests, required tokens), can receive progress even when not started, can be repeatable, etc. I describe the tasks in Google spreadsheets, and for most simple cases, this is the most convenient way.

Saver Module

Everything related to data saving is here. The module contains a save table and allows adding other data tables to it (these can be other modules or player data). Saving happens every N seconds and at certain events. There is also a built-in migration system that you can write and apply to the profile before it is loaded into the game.

Map Grid Modules

There are three modules with the same interface -

grid, hexgrid, and isogrid. These are three grids that you can use in the game, as well as in the Tiled editor. The most complex of these is probably hexgrid. Counting hexes positions is quite tricky. It’s not pixel-perfect, but it’s good enough for the most games.

Token Module

Tokens - any countable item that a player can receive or spend. This module contains complete work with such data. All tokens belong to some container. For example, there is a wallet module - a copy of this module, but it works directly with the player’s global token container (convenient and fast!). Containers can be anything - from a list of items in a chest to some player statistics.

I had a match-3 game where there were lives restores on a timer. This module also allows you to set the restore parameters for a token, and it will be restored on a timer (even offline).

Game Module

Here are things mainly for player analytics, but there is one important function - get_time. And also three ways to count it. The third one is not done, it’s server, but it can be done!

So, the first one is local - this is the simple time that we take through socket.gettime() and no tricks.

The second, more interesting for you, is local_uptime, which uses the library Uptime, it takes time starting from the moment the OS starts. Why is this useful? Because it does not allow you to manipulate your in-game timers, simply by shifting the time on the device. So you can see how easy it is to do this in your game.

Debug

Since there is access to many game systems already within Eva, there are a few convenient things you can do. Perhaps the most convenient one I use is saving and loading the game using hotkeys (ctrl/alt + [1, 2, 3]). This allows you to save a specific moment during the development of any element and load it when needed. I also bind language switching, profile clearing, and game reloading to hotkeys.


Eva powered :muscle:

Eva Libraries

There are several things that may be of interest to you.

Logging

Eva has its own logger that can format its messages. I find it quite convenient to use and try to cover most of the logic with logs. But during development, I still mostly use regular print() :face_with_hand_over_mouth:

The logger messages look like this (the file paths are clickable!):

D[eva.db]<eva/modules/db.lua:67>: Load JSON data {name = "Maps",path = "/resources/json/maps.json"}
D[eva.proto]<eva/modules/proto.lua:113>: Load protofile {path = "/resources/eva.proto"}
I[eva.device]<eva/modules/device.lua:159>: Device ID {device_id = "0e4b8b6a-da28-4a0c-caf6-883bdb6c0ebc"}
D[eva.game]<eva/modules/game.lua:49>: Sync time with uptime {diff = 1683626024.5198,prev_time = 127347,time = 113312}
I[eva.saver]<eva/modules/saver.lua:225>: Save successful loaded {migration_version = 0,version = 74}
D[eva.events]<eva/modules/events.lua:22>: Event {event = "eva.game.new_session"}

Events

Everything within Eva is built on an event system. It allows subscribing to events from anywhere, even from a different context. Before calling an event, its context will change to the context it was subscribed to (via lua_script_instance extension). This allows creating a shared event bus that anyone can subscribe to.

For example, if I earn a coin in the main game script and the GUI panel is subscribed to it, it can instantly receive this event and update GUI node data.

Tweener

A small module that allows running any tweens like in go.animate or gui.animate, but using a timer. A common use case for me is smoothly animating the player’s score and displaying it as text.

Example:

local tweener = require("eva.libs.tweener")

tweener.tween(tweener.outSine, current_zoom, zoom, time, function(value, is_end)
    rendercam.set_ortho_scale(value, state.cam_id)
    if is_end then
        M.set_zoom(zoom)
    end
end)

Smart Value

This is one of my old wrappers around a simple number with some useful methods. It includes protection against memory scanning (values are not stored directly), events on value changes, min/max values, current visual value for GUI, and additional checking functions to improve code readability.

Luax

A large collection of small functions that can be useful as an extension of the Lua standard library.

Links

Outro

Thank you for your attention! I hope you find it interesting to explore Eva and can find something useful for yourself. Leave your feedback and let us know what you liked the most!

:heart: Support :heart:

Your donation helps me stay engaged in creating valuable projects for Defold. If you appreciate what I’m doing, please consider supporting me!

Github-sponsors Ko-Fi BuyMeACoffee

23 Likes

Wow, a lot of useful things! Worth checking out, you got me interested :heart_eyes:

4 Likes

Amazing! Thanks for sharing.

3 Likes

There are three libraries from Eva that now have their repositories, allowing users to use them separately.

More info here:

Defold Log - Context logger with performance metrics for Defold

Defold Event - Cross-Context Defold Event System

Defold Tweener - Timer Based Defold Tween Library

8 Likes

Thanks for sharing

1 Like