JevaEngine - Underground

Hmm, but casting a shadow with an Area object is a lot less involved than casting a shadow with a BufferedImage - all I have to do is subtract from the Area and reassign that area to a different render routine - which is why I say it might not really help with performance at all (in my case) by dropping shadows. Idk though, I’d actually need to test it.

I’m pretty sure the RadialGradientPaint is hardware accelerated - i.e in the backend it is probably using a pixel shader of some sort. I know this because I tried creating my own radial gradient paint implementing Paint - and is really simple in nature (something like RadialGradientPaint) and I lost the hardware acceleration and it got really slow. Plus a pixel-shader for radial-gradient would be really easy to implement I am sure the JRE accelerates it.

I’ll take a look at my code and try to extract the lighting sub-system - shouldn’t be too hard to do. I’ll post it here when I do.

Just added a command console that gives the user access to the scripting of the engine in real-time. Scripting has been a feature for a long while but now there is a command console to execute on-the-fly scripts as well. It’s pretty cool and it only took about 45 minutes to implement (since the infrastructure has always been there). I show it off along with the new world time system (I am going to add weather, it just takes a bit more work to setup the particle emitter etc)):

Camstasia (the program I use to record the game to youtube) lags the bloody hell out of this computer, but IMO it performed alright… You have to watch this in 720p - otherwise you can’t read the scripts…

pmf7vrsz0TY

The lighting code is essentially this there is a SceneLighting object that manages the different lights on the scene - still though I haven’t found time to unmangle it from the engine because I was busy fixing a few bugs that came to my attention thanks to the addition of the console.

You can play run the applet here:
http://gamejolt.com/games/rpg/jevaengine-project-d0/16225/

It’s a pre-release (I.e, this is hidden content) so don’t rate it etc I don’t really want a lot of people catching wind of it’s accessibility.

I mainly do this because its at a stage where it is worth playing with. Here is the guide for the command line system and some notes:

  • Only map/almostatcontrol.jmp has a script which relates world time with an ambient lighting. So if you want to see the effects of world time, you must be on that map to do it.

  • Precaching isn’t fully implemented since it hasn’t been an issue until now - essentially this means that you might get temporary pauses in the game as it prepares and caches resources that haven’t yet been accessed but are just then being accessed via a script etc.

  • Any textarea can be scrolled through with the middle mouse scroll AFTER selecting the textarea

Command Terminal Menu:

  • Visibility can be toggled by using the ~ key - except when an editable text-area is selected

  • The command line uses JavaScript, there is a text area adjacent to the red pointer, select it and write your scripts. After you entered your script, there are two commands you can use:

  • This doesn’t disclose all available commands because it would take a while to write that up…

CTRL + E (probably the only one you need) executes the script you’ve entered. If you’re script declares functions or variables, they will be added to the global scope so they can be used later.

CTRL + L - Loads the script so that any scripts there on out are executed in the context of what you’ve just typed in.

  • The green text of the text-area will spit out notes when executing your script - and if it evaluates to something, it will print out the evaluation. If there is an error in your script, it will display a cryptic error message (the output textarea does not scroll automatically, you must select it and scroll via middle mouse wheel)

There are three global variables accessible by the command like:
game
- Used to acquire world script bridge, to load a world and to get the player entity
core
- Used for nothing other than debugging purposes.
me
- Used to access commands that are relevant to the console (or executing object) kind of like the ‘this’ keyword. In the command console you can use it to echo and clear

Functions exposed by ‘me’ in command console
clear(); - clears the console’s output textarea
echo(message); - Echos message to output console.

i.e:
me.clear();
me.echo(‘hello’);

Functions exposed by ‘game’ in command console
getPlayer() returns an instance of player’s script bridge. Refer to ‘Commands Exposed by Player ScriptBridge’
getWorld() returns an instnace of world’s script bridge. Refer to ‘Commands Exposed by World ScriptBridge’
loadWorld(url) loads the world located at the given URL.

There are three maps that exist in the game’s File-System:
map/almostatcontrol.jmp
map/firstencounter.jmp
map/enterance.jmp

Functions exposed by Player ScriptBridge in command console & All NPCs

Just For Player:
getQuest(questName) returns an instance of the given quest tailored to that player. Provides ability to check and set quest states.

For All NPCs & Player:

getLocation() returns a Vector of integer components X, Y describing the player’s location.

Example:

me.echo('Players X location is: ' + game.getPlayer().getLocation().x);

setLocation(x, y) Sets the world location to (x, y)

Example:

game.getPlayer().setLocation(0, 0);

var eric = game.getWorld().getEntity('eric');

if(eric != null)
    game.getPlayer().setLocation(eric.getLocation().x, eric.getLocation().y + 1);
else
    me.echo('The NPC Eric could not be found!');

moveTo(x, y, tolerance) - Entity en-queues asynchronous task to walk to location (x, y) with an acceptable ‘tolerance’ i.e radius they are allowed to be in before declaring failure to accomplish task.

Example:


game.getPlayer().moveTo(0, 0, 1);

attack(target) - en-queues asynchronous task to attack the given target, or fails if equip weapon allows for such range

Example:

var player = game.getPlayer();
var spider = game.getWorld().getEntity('spider');
spider.moveTo(player.getLocation().x, player.getLocation().y, 1);
spider.attack(player);
player.attack(spider);

leave() - En-queues asynchronous task to have the character leave the scene

Example:

var eric = game.getWorld().getEntity('eric');
//Tell eric, first move to the coordinate 0,0
eric.moveTo(0,0,1);
//Then once you arrive (or if the move tasks is otherwise 'completed') leave the world
eric.leave();

isConflictingAllegiance(target) - Returns true if is in conflicting allegiance with target (I.E target is enemy)
Example:

var spider = game.getWorld().getEntity('spider');
if(spider.isConflictingAllegiance(game.getPlayer())
{
    spider.moveTo(game.getPlayer().getLocation().x, game.getPlayer().getLocation().y, 1);
    spider.attack(game.getPlayer());
}

getHealth() Returns an integer value which is the current health of the character, all characters have a health between 0 and 100 as of now - though that can change depending on the character’s configuration file.

setHealth(health) Sets the health of the character.

example:


if(game.getPlayer().getHealth() < 20);
    game.getPlayer().setHealth(100);

addItem(itemDescriptor, quantity) - Adds an item to character’s inventory. Returns the number of that item added which can differ from quantity if the inventory is full before quantity is reached.

hasItem(itemDescriptor, quantity) - returns true of the player is in possession of quantity number of itemDescriptor

[b]removeItem(itemDescriptor, quantity)[b] - Behaves exactly has addItem only removes item. Returned value can differ from quantity if less than quantity of itemDescriptor is contained in inventory

Example

var player = game.getPlayer();
var eric = game.getWorld().getEntity('eric');

if(player.hasItem('item/healthpack.jitm', 1))
{
    me.echo('Fair trade!');
    if(eric.hasItem('item/rifle.jitm', 1)
    {
        player.removeItem('item/healthpack.jitm', 1);
        player.addItem('item/rifle.jitm', 1);
        eric.addItem('item/healthpack.jitm');
    }else
        me.echo('Looks like eric doesnt have anything left to trade!');
}

wonder(radius) En-queues asynchronous wonder task to randomly move around.

distance(target) Returns the distance (in tiles) from the given target

look() Has the character look around it’s given area (using is sight properties described in its configuration file). Any found objects cause the object to invoke a onFound() routine - you can’t really use this via the command console only via entity scripts.

loadState(path) Restores the state of the entity as described by the state located at the given path. The current release uses memory states so this is sort of like a memory virtual filesystem.

saveState(path) Saves the state of the entity to the given path.

Functions exposed by World ScriptBridge in command console

setAmbientLight(r, g, b, a) - Configure’s world’s ambient light.

setHour(hour) - Sets world’s time
setMinute(minute)
setSecond(second)
setHour(hour) - 24 hour time

getHour, minute etc…

setTimeMultiplier(multiplier)

Example
game.getWorld().setTimeMultiplier(10000);

createEntity(name, className, npcFile)

  • className has to be jevarpg.RpgCharacter
  • npcFile can be:
    npcs/innocentspider.jnpc
    npcs/player.jnpc
    npcs/spider_almostatcontrol.jnpc

getEntity(entityName)

That is a long read. Will try it out later. Keep it up. Check out my lighting post. ::slight_smile:

Lol, yeah sorry for the long read. I’ll definitely take a look at your lighting code.

Today I’m going to start planning and hopefully get started on working on a Server Module Extention to the core engine, likewise write a Client module for the Rpg extention. I think adding a bit of networking into the engine would be really cool.

Anyway for those curious how I am partitioning things:

This thread is essentially my development log, when I develop a major tech demo etc I will post in the releases, but this thread is primarily just for news etc regarding the engine.

Network Subsystem is nearly completed, I believe I will have some basic networking to show off soon.

It looks like server-side scripted entities are actually going to be quite easy to implement, and all features in the game (minus dialog which will require some tweaking since dialogs pause the server-side world state) will seamlessly be handled on the server-side and fed to the clients.

The network-subsystem took a bit of work, but with the current implementation I am hoping for minimum bandwidth consumption.

The networking is going to be implemented outside of the engine’s core. This makes most sense to me since the actual model used for networking can be most optimally chosen outside of the core of the engine. I.e, if movement is strictly tile-based (as it is for the RPG Extension) then movement can be abstracted to a very low-bandwidth per-tile level. If it is more complex than that (i.e, not strictly tile based) then obviously it may require some more bandwidth intensive operations etc to portray velocity, acceleration location etc and a more complex client-side prediction.

The current networking model communicates to clients using snapshots broadcasted at a fixed frequency. Using snapshots allows data network data to be queued for a fixed time period and then dispatched to the client(s) (and vise-versa) This is an avantage as compression ratios are best with larger chunks of data and it avoids redudant data being dispatched over at a very high frequency (wasting bandwidth.)

Anyway, updates to follow.

4aJhpaTUDro

Networking is fully operational:

Here is a demo of the game server and client. I am still polishing up a few things then I intend on creating a simple game out of it to do some server load testing. The server is on the left, the client on the right. This demo illustrates only one client - though the server is capable of managing many clients.

The Screen Recorder I use eats up CPU Cycles like a monster so I can’t record with a decent frame-rate.

Load Times:

The load times for the spider sprite in particular is quite slow. This is due to the Spider’s texture file being absurdly large and inefficeint. You will see the client Freeze and the server Freeze as the spider is loaded into the world for about 5s, usually the assets would go through a precache process to avoid the load times while in-game, but precaching is not an immdediate concearn and has thus been thrown on-to the ‘do later’ task-list.

The load times for worlds are slow, this is because the worlds are currently stored in a plain-text (sort of like XML but with less overhead) format. This means that with large worlds and many layers it takes a large amount of CPU time to parse them. Optimally (and in later stages of development) these worlds will be stored in a binary format. Once the map files have actually been parsed, my profiler informs me that the actual LOADING of the map using the intermediate data structures fromed via the parsing process is very quick.

Security from client-side tampering:

In theory (if I’m not missing any bugs here) it is impossible for the clients to alter the state explicitly of any server entity without first asking the server so the game should be safe from game tampering. Additionally I have employed data encryption and code obfuscation\optimizations to ecourage would-be hackers to give up. The worst someone could do is to throw the client out of sync with the server, but it would have no effect on other clients or the server.

Please post any feedback, it is appreciated.

What I am doing now:

  • I will be resolving a very obscure and difficult to reproduce bug in the server
  • Polishing & finalizing the server & networking code.
  • Creating an actual multiplayer game out of the recent advancements in the engine to do some load-testing on the server.

I’m not sure where I am going to deploy the server… I can’t deploy it on this piece of crap because it barely does two things at once and I need access to my IDE. I have another computer I could deploy it on but it isn’t ‘mine’ per se.

JevaEngine now has a very solid networking implementation, that includes entities such as AreaTriggers and NPC Characters and various other basic entities (doors etc…)

The way it works is something like:

  • Every networked entity has a script associated with it. There is a client script (stored and executed on the client) and a server script (stored and executed on the server) Both work exactly the same as entity scripts did before (i.e, with single player.) Server scripts work on the entity for i.e movements etc. Client scripts do the same for strictly client-side tasks (like playing the ‘die sound’ when a character dies)

I am going to be releasing a basic game to demo this, the game works something like this (and will be published on game jolt) I will deploy the server on my computer which should be good for ~45-50 players with 175 complex entities (that is, entities with very active AI constantly mutating states that need to be shared accross clients):

  1. Players spawn as soldiers on the map - except for the two top-ranking players of the previous map. Soliders play a sort of Rpg Perspective - they can loot for better weapons and level up per round (i.e, after the round is reset - their character is reset) If I can, for the first couple of releases, I want to avoid having to keep track of players beyond individual rounds etc because that requires a backend database implementation that detracts for the purpose of the first couple of releases requires more serious security considerations.

  2. The first of the two top-ranking players will be the master of the World’s spider hive. I.e, they play a sort of RTS perspective of the game and control the spider NPC army of the multiplayer game.

  3. The second of the two top-ranking players will be the same except for Zombies

  4. Spiders and Zombies work together to kill the soldiers and vise-versa. Trophies are earned for being a top-ranked player for a given period of time, killing x spiders etc.

Latest Networking Demonstration:

v-52aKJ4Smo