Improved World update performance. Decreased save file size. Added Harvester NPC #19.

This commit is contained in:
simon 2017-12-16 15:40:03 -05:00
parent cd41db9e58
commit 3548928218
20 changed files with 102 additions and 37 deletions

View File

@ -77,8 +77,8 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit {
@Override @Override
public JSONObject serialise() { public JSONObject serialise() {
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
json.put("id", getObjectId()); json.put("i", getObjectId());
json.put("type", ID); json.put("t", ID);
json.put("x", getX()); json.put("x", getX());
json.put("y", getY()); json.put("y", getY());
json.put("direction", getDirection().ordinal()); json.put("direction", getDirection().ordinal());
@ -98,7 +98,7 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit {
public static Cubot deserialize(JSONObject json) { public static Cubot deserialize(JSONObject json) {
Cubot cubot = new Cubot(); Cubot cubot = new Cubot();
cubot.setObjectId((int) (long) json.get("id")); cubot.setObjectId((int) (long) json.get("i"));
cubot.setX((int) (long) json.get("x")); cubot.setX((int) (long) json.get("x"));
cubot.setY((int) (long) json.get("y")); cubot.setY((int) (long) json.get("y"));
cubot.hp = (int) (long) json.get("hp"); cubot.hp = (int) (long) json.get("hp");

View File

@ -25,7 +25,7 @@ public class CubotPlugin extends ServerPlugin implements GameObjectDeserializer,
@Override @Override
public GameObject deserializeObject(JSONObject object) { public GameObject deserializeObject(JSONObject object) {
int objType = (int) (long) object.get("type"); int objType = (int) (long) object.get("t");
if (objType == Cubot.ID) { if (objType == Cubot.ID) {

View File

@ -29,6 +29,7 @@ public class UserCreationListener implements GameEventListener {
GameServer.INSTANCE.getConfig().getInt("new_user_worldX"), GameServer.INSTANCE.getConfig().getInt("new_user_worldX"),
GameServer.INSTANCE.getConfig().getInt("new_user_worldY"))); GameServer.INSTANCE.getConfig().getInt("new_user_worldY")));
cubot.getWorld().getGameObjects().add(cubot); cubot.getWorld().getGameObjects().add(cubot);
cubot.getWorld().incUpdatable();
cubot.setObjectId(GameServer.INSTANCE.getGameUniverse().getNextObjectId()); cubot.setObjectId(GameServer.INSTANCE.getGameUniverse().getNextObjectId());

View File

@ -1,6 +1,7 @@
package net.simon987.npcplugin; package net.simon987.npcplugin;
import net.simon987.server.GameServer;
import net.simon987.server.assembly.Util; import net.simon987.server.assembly.Util;
import net.simon987.server.game.Direction; import net.simon987.server.game.Direction;
import net.simon987.server.game.GameObject; import net.simon987.server.game.GameObject;
@ -83,7 +84,18 @@ public class HarvestTask extends NPCTask {
} else { } else {
if (nextWorldDirection == null) { if (nextWorldDirection == null) {
//Stay near the center of the map 50% of the time
if (random.nextBoolean()) {
nextWorldDirection = Direction.getDirectionTo(npc.getX(), npc.getY(),
GameServer.INSTANCE.getConfig().getInt("new_user_worldX"),
GameServer.INSTANCE.getConfig().getInt("new_user_worldY"));
} else {
nextWorldDirection = Direction.getDirection(random.nextInt(3)); nextWorldDirection = Direction.getDirection(random.nextInt(3));
}
pause += 6; pause += 6;
} }
npc.gotoWorld(nextWorldDirection); npc.gotoWorld(nextWorldDirection);

View File

@ -37,14 +37,14 @@ public class HarvesterNPC extends NonPlayerCharacter {
public JSONObject serialise() { public JSONObject serialise() {
JSONObject json = super.serialise(); JSONObject json = super.serialise();
json.put("id", getObjectId()); json.put("i", getObjectId());
json.put("x", getX()); json.put("x", getX());
json.put("y", getY()); json.put("y", getY());
json.put("direction", getDirection().ordinal()); json.put("direction", getDirection().ordinal());
json.put("hp", hp); json.put("hp", hp);
json.put("energy", energy); json.put("energy", energy);
json.put("action", getAction().ordinal()); json.put("action", getAction().ordinal());
json.put("type", 10); json.put("t", 10);
return json; return json;
} }
@ -52,7 +52,7 @@ public class HarvesterNPC extends NonPlayerCharacter {
public static HarvesterNPC deserialize(JSONObject json) { public static HarvesterNPC deserialize(JSONObject json) {
HarvesterNPC npc = new HarvesterNPC(); HarvesterNPC npc = new HarvesterNPC();
npc.setObjectId((int) (long) json.get("id")); npc.setObjectId((int) (long) json.get("i"));
npc.setX((int) (long) json.get("x")); npc.setX((int) (long) json.get("x"));
npc.setY((int) (long) json.get("y")); npc.setY((int) (long) json.get("y"));
npc.hp = (int) (long) json.get("hp"); npc.hp = (int) (long) json.get("hp");

View File

@ -57,8 +57,6 @@ public abstract class NonPlayerCharacter extends GameObject implements Updatable
public boolean gotoWorld(Direction direction) { public boolean gotoWorld(Direction direction) {
System.out.println("going " + direction);
if (direction == Direction.NORTH) { if (direction == Direction.NORTH) {
if (!moveTo(8, 0, 0)) { if (!moveTo(8, 0, 0)) {
setDirection(Direction.NORTH); setDirection(Direction.NORTH);

View File

@ -22,7 +22,7 @@ public class NpcPlugin extends ServerPlugin implements GameObjectDeserializer {
@Override @Override
public GameObject deserializeObject(JSONObject object) { public GameObject deserializeObject(JSONObject object) {
int objType = (int) (long) object.get("type"); int objType = (int) (long) object.get("t");
if (objType == HarvesterNPC.ID) { if (objType == HarvesterNPC.ID) {
return HarvesterNPC.deserialize(object); return HarvesterNPC.deserialize(object);

View File

@ -43,9 +43,8 @@ public class WorldUpdateListener implements GameEventListener {
npc.setX(p.x); npc.setX(p.x);
npc.setY(p.y); npc.setY(p.y);
world.getGameObjects().add(npc); world.getGameObjects().add(npc);
world.incUpdatable();
} }
} }

View File

@ -16,7 +16,7 @@ public class BiomassBlob extends GameObject implements InventoryHolder {
/** /**
* Style of the blob (Only visual) * Style of the blob (Only visual)
*/ */
private int style; // private int style;
private static final int ITM_BIOMASS = 1; private static final int ITM_BIOMASS = 1;
@ -30,12 +30,12 @@ public class BiomassBlob extends GameObject implements InventoryHolder {
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
json.put("type", ID); json.put("t", ID);
json.put("id", getObjectId()); json.put("i", getObjectId());
json.put("x", getX()); json.put("x", getX());
json.put("y", getY()); json.put("y", getY());
json.put("biomassCount", biomassCount); json.put("b", biomassCount);
json.put("style", style); // json.put("style", style);
return json; return json;
} }
@ -49,23 +49,23 @@ public class BiomassBlob extends GameObject implements InventoryHolder {
this.biomassCount = biomassCount; this.biomassCount = biomassCount;
} }
public int getStyle() { // public int getStyle() {
return style; // return style;
} // }
//
public void setStyle(int style) { // public void setStyle(int style) {
this.style = style; // this.style = style;
} // }
public static BiomassBlob deserialize(JSONObject json) { public static BiomassBlob deserialize(JSONObject json) {
BiomassBlob biomassBlob = new BiomassBlob(); BiomassBlob biomassBlob = new BiomassBlob();
biomassBlob.setObjectId((int) (long) json.get("id")); biomassBlob.setObjectId((int) (long) json.get("i"));
biomassBlob.setX((int) (long) json.get("x")); biomassBlob.setX((int) (long) json.get("x"));
biomassBlob.setY((int) (long) json.get("y")); biomassBlob.setY((int) (long) json.get("y"));
biomassBlob.style = (int) (long) json.get("style"); // biomassBlob.style = (int) (long) json.get("style");
biomassBlob.biomassCount = (int) (long) json.get("biomassCount"); biomassBlob.biomassCount = (int) (long) json.get("b");
return biomassBlob; return biomassBlob;
} }

View File

@ -23,7 +23,7 @@ public class BiomassPlugin extends ServerPlugin implements GameObjectDeserialize
@Override @Override
public GameObject deserializeObject(JSONObject object) { public GameObject deserializeObject(JSONObject object) {
int objType = (int) (long) object.get("type"); int objType = (int) (long) object.get("t");
if (objType == BiomassBlob.ID) { if (objType == BiomassBlob.ID) {

View File

@ -65,7 +65,7 @@ public class WorldUtils {
BiomassBlob biomassBlob = new BiomassBlob(); BiomassBlob biomassBlob = new BiomassBlob();
biomassBlob.setObjectId(GameServer.INSTANCE.getGameUniverse().getNextObjectId()); biomassBlob.setObjectId(GameServer.INSTANCE.getGameUniverse().getNextObjectId());
biomassBlob.setStyle(0); //TODO: set style depending on difficulty level? or random? from config? // biomassBlob.setStyle(0); //TODO: set style depending on difficulty level? or random? from config?
biomassBlob.setBiomassCount(yield); biomassBlob.setBiomassCount(yield);
biomassBlob.setX(p.x); biomassBlob.setX(p.x);
biomassBlob.setY(p.y); biomassBlob.setY(p.y);

View File

@ -147,8 +147,12 @@ public class GameServer implements Runnable {
//Process each worlds //Process each worlds
//Avoid concurrent modification //Avoid concurrent modification
ArrayList<World> worlds = new ArrayList<>(gameUniverse.getWorlds()); ArrayList<World> worlds = new ArrayList<>(gameUniverse.getWorlds());
int updatedWorlds = 0;
for (World world : worlds) { for (World world : worlds) {
if (world.shouldUpdate()) {
world.update(); world.update();
updatedWorlds++;
}
} }
//Save //Save
@ -163,7 +167,8 @@ public class GameServer implements Runnable {
socketServer.tick(); socketServer.tick();
LogManager.LOGGER.info("Processed " + gameUniverse.getWorlds().size() + " worlds"); LogManager.LOGGER.info("Processed " + gameUniverse.getWorlds().size() + " worlds (" + updatedWorlds +
") updated");
} }
/** /**

View File

@ -17,6 +17,7 @@ public class Main {
//Load //Load
GameServer.INSTANCE.getGameUniverse().load(new File("save.json")); GameServer.INSTANCE.getGameUniverse().load(new File("save.json"));
SocketServer socketServer = new SocketServer(new InetSocketAddress(config.getString("webSocket_host"), SocketServer socketServer = new SocketServer(new InetSocketAddress(config.getString("webSocket_host"),
config.getInt("webSocket_port")), config); config.getInt("webSocket_port")), config);

View File

@ -58,4 +58,26 @@ public enum Direction {
} }
} }
/**
* Get direction to move from (x1, y1) to (x2, y2)
*/
public static Direction getDirectionTo(int x1, int y1, int x2, int y2) {
int dx = x2 - x1;
int dy = y2 - y1;
if (dx > 0 && dx >= dy) {
return Direction.EAST;
} else if (dx < 0 && dx <= dy) {
return Direction.WEST;
} else if (dy > 0 && dy >= dx) {
return Direction.NORTH;
} else if (dy < 0 && dy <= dx) {
return Direction.SOUTH;
} else {
return null;
}
}
} }

View File

@ -82,7 +82,9 @@ public abstract class GameObject implements JSONSerialisable {
if (leftWorld != null) { if (leftWorld != null) {
world.getGameObjects().remove(this); world.getGameObjects().remove(this);
world.decUpdatable();
leftWorld.getGameObjects().add(this); leftWorld.getGameObjects().add(this);
leftWorld.incUpdatable();
setWorld(leftWorld); setWorld(leftWorld);
x = World.WORLD_SIZE - 1; x = World.WORLD_SIZE - 1;
@ -99,7 +101,9 @@ public abstract class GameObject implements JSONSerialisable {
if (rightWorld != null) { if (rightWorld != null) {
world.getGameObjects().remove(this); world.getGameObjects().remove(this);
world.decUpdatable();
rightWorld.getGameObjects().add(this); rightWorld.getGameObjects().add(this);
rightWorld.incUpdatable();
setWorld(rightWorld); setWorld(rightWorld);
x = 0; x = 0;
@ -117,7 +121,9 @@ public abstract class GameObject implements JSONSerialisable {
if (upWorld != null) { if (upWorld != null) {
world.getGameObjects().remove(this); world.getGameObjects().remove(this);
world.decUpdatable();
upWorld.getGameObjects().add(this); upWorld.getGameObjects().add(this);
upWorld.incUpdatable();
setWorld(upWorld); setWorld(upWorld);
y = World.WORLD_SIZE - 1; y = World.WORLD_SIZE - 1;
@ -135,7 +141,9 @@ public abstract class GameObject implements JSONSerialisable {
if (downWorld != null) { if (downWorld != null) {
world.getGameObjects().remove(this); world.getGameObjects().remove(this);
world.decUpdatable();
downWorld.getGameObjects().add(this); downWorld.getGameObjects().add(this);
downWorld.incUpdatable();
setWorld(downWorld); setWorld(downWorld);
y = 0; y = 0;

View File

@ -30,6 +30,11 @@ public class World implements JSONSerialisable {
private ArrayList<GameObject> gameObjects = new ArrayList<>(16); private ArrayList<GameObject> gameObjects = new ArrayList<>(16);
/**
* If this number is greater than 0, the World will be updated.
*/
private int updatable = 0;
public World(int x, int y, TileMap tileMap) { public World(int x, int y, TileMap tileMap) {
this.x = x; this.x = x;
this.y = y; this.y = y;
@ -114,13 +119,15 @@ public class World implements JSONSerialisable {
for (GameObject obj : gameObjects_) { for (GameObject obj : gameObjects_) {
objects.add(obj.serialise()); objects.add(obj.serialise());
} }
json.put("objects", objects); json.put("o", objects);
json.put("terrain", tileMap.serialise()); json.put("t", tileMap.serialise());
json.put("x", x); json.put("x", x);
json.put("y", y); json.put("y", y);
json.put("u", updatable);
return json; return json;
} }
@ -145,10 +152,11 @@ public class World implements JSONSerialisable {
World world = new World(); World world = new World();
world.x = (int) (long) json.get("x"); world.x = (int) (long) json.get("x");
world.y = (int) (long) json.get("y"); world.y = (int) (long) json.get("y");
world.updatable = (int) (long) json.get("u");
world.tileMap = TileMap.deserialize((JSONObject) json.get("terrain")); world.tileMap = TileMap.deserialize((JSONObject) json.get("t"));
for (JSONObject objJson : (ArrayList<JSONObject>) json.get("objects")) { for (JSONObject objJson : (ArrayList<JSONObject>) json.get("o")) {
GameObject object = GameObject.deserialize(objJson); GameObject object = GameObject.deserialize(objJson);
@ -258,4 +266,15 @@ public class World implements JSONSerialisable {
return gameObjects; return gameObjects;
} }
public void incUpdatable() {
updatable++;
}
public void decUpdatable() {
updatable--;
}
public boolean shouldUpdate() {
return updatable > 0;
}
} }

View File

@ -17,7 +17,7 @@ cert_path=certificates
# ---------------------------------------------- # ----------------------------------------------
# Length of a tick in ms # Length of a tick in ms
tick_length=250 tick_length=125
# Default offset of the origin (starting point of code execution) in words # Default offset of the origin (starting point of code execution) in words
org_offset=512 org_offset=512
# Address of the stack bottom # Address of the stack bottom

Binary file not shown.

Binary file not shown.

Binary file not shown.