faster jump response, more documentation (ABOUT, MECHANICS)

Former-commit-id: 1392de885f6cbcd48102a20d707f3a9e5a4df9ca
Former-commit-id: e7908894aef53fde4b1cf391e48ac9b7fd3f0a13
This commit is contained in:
Song Minjae
2016-02-24 12:44:32 +09:00
parent 0b6d8ff44d
commit 19630e2147
15 changed files with 250 additions and 210 deletions

4
res/config_default.json Normal file
View File

@@ -0,0 +1,4 @@
{
"smoothlighting" : true,
"imtooyoungtodie" : false
}

View File

@@ -1,4 +1,4 @@
"STRING_ID";"IETF language tag(s) without dash";"enUS";"frFR";"esES";"deDE";"itIT";"ptBR";"ptPT";"ruRU";"elGR";"trTR";"daDK";"noNB";"svSE";"nlNL";"plPL";"fiFI";"jaJP";"zhCN";"zhTW";"koKR";"csCZ";"huHU";"roRO";"thTH";"bgBG";"heIL";"jakanaJP"
"STRING_ID";"IETF language tag(s) without dash";"enUS";"frFR";"esES";"deDE";"itIT";"ptBR";"ptPT";"ruRU";"elGR";"trTR";"daDK";"noNB";"svSE";"nlNL";"plPL";"fiFI";"jaJP";"zhCN";"zhTW";"koKR";"csCZ";"huHU";"roRO";"thTH";"bgBG";"heIL";"jakanaJP";"isIC"
"APP_CALIBRATE_YOUR_MONITOR";;"Best player experience can be achieved with properly calibrated monitor. If you have not, please do it before you play.";"Meilleure expérience de joueur peut être réalisé avec écran correctement calibré. Si vous ne l'avez pas, s.v.p. le calibrez avant de jouer.";;;;;;;;;;;;;;;"このゲームは、適切に校正したモニターから最高のプレイができます。校正していなければ、プレイする前に校正して下さい。";;;"본 게임은 적절히 보정된 모니터에서 최상으로 즐길 수 있습니다. 보정하지 않았다면 플레이하기 전에 보정해 주십시오.";;;;;;;"この ゲームは てきせつに うせい した モニターから さいこうの プレイが できます。うせい して いなければ プレイする まえに うせい して ください。"
"COPYRIGHT_MSG";;"All rights reserved.";"Tous les droits sont réservés.";;;;;;;;;;;;;;;"全著作権所有。";;;"모든 권리 보유.";;;;;;;"ぜん ちょさくけん しょゆう。"
"APP_CALIBRATE_YOUR_MONITOR";;"Best player experience can be achieved with properly calibrated monitor. If you have not, please do it before you play.";"Meilleure expérience de joueur peut être réalisé avec écran correctement calibré. Si vous ne l'avez pas, s.v.p. le calibrez avant de jouer.";;;;;;;;;;;;;;;"このゲームは、適切に調整したモニターから最高のプレイができます。調整していなかったら、プレイする前に調整して下さい。";;;"본 게임은 적절히 보정된 모니터에서 최상으로 즐길 수 있습니다. 보정하지 않았다면 플레이하기 전에 보정해 주십시오.";;;;;;;"この ゲームは てきせつに ちょうせい した モニターから さいこうの プレイが できます。ちょうせい して いなかったら プレイする まえに ちょうせい して ください。";"Best leikmaður reynsla er getur náðist með rétt kvarðaður skjárinn. Ef þú ekki gerðir, gerðu svo vel að kvarða áður en þú spilar."
"COPYRIGHT_MSG";;"All rights reserved.";"Tous les droits sont réservés.";;;;;;;;;;;;;;;"全著作権所有。";;;"모든 권리 보유.";;;;;;;"ぜん ちょさくけん しょゆう。";"Allur réttur áskilinn."
1 STRING_ID IETF language tag(s) without dash enUS frFR esES deDE itIT ptBR ptPT ruRU elGR trTR daDK noNB svSE nlNL plPL fiFI jaJP zhCN zhTW koKR csCZ huHU roRO thTH bgBG heIL jakanaJP isIC
2 APP_CALIBRATE_YOUR_MONITOR Best player experience can be achieved with properly calibrated monitor. If you have not, please do it before you play. Meilleure expérience de joueur peut être réalisé avec écran correctement calibré. Si vous ne l'avez pas, s.v.p. le calibrez avant de jouer. このゲームは、適切に校正したモニターから最高のプレイができます。校正していなければ、プレイする前に校正して下さい。 このゲームは、適切に調整したモニターから最高のプレイができます。調整していなかったら、プレイする前に調整して下さい。 본 게임은 적절히 보정된 모니터에서 최상으로 즐길 수 있습니다. 보정하지 않았다면 플레이하기 전에 보정해 주십시오. この ゲームは てきせつに こうせい した モニターから さいこうの プレイが できます。こうせい して いなければ プレイする まえに こうせい して ください。 この ゲームは てきせつに ちょうせい した モニターから さいこうの プレイが できます。ちょうせい して いなかったら プレイする まえに ちょうせい して ください。 Best leikmaður reynsla er getur náðist með rétt kvarðaður skjárinn. Ef þú ekki gerðir, gerðu svo vel að kvarða áður en þú spilar.
3 COPYRIGHT_MSG All rights reserved. Tous les droits sont réservés. 全著作権所有。 모든 권리 보유. ぜん ちょさくけん しょゆう。 Allur réttur áskilinn.
4

View File

@@ -17,7 +17,7 @@ public class CSVFetcher {
private static StringBuffer csvString;
public static List<CSVRecord> readCSV(String csvFilePath) throws IOException {
csvString = new StringBuffer();
csvString = new StringBuffer(); // reset buffer every time it called
readCsvFileAsString(csvFilePath);
CSVParser csvParser = CSVParser.parse(csvString.toString()

View File

@@ -6,6 +6,8 @@ import com.google.gson.JsonParser;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Iterator;
/**
* Created by minjaesong on 16-02-15.
@@ -15,7 +17,7 @@ public class JsonFetcher {
private static StringBuffer jsonString;
public static JsonObject readJson(String jsonFilePath) throws IOException {
jsonString = new StringBuffer();
jsonString = new StringBuffer(); // reset buffer every time it called
readJsonFileAsString(jsonFilePath);
JsonParser jsonParser = new JsonParser();
@@ -24,6 +26,14 @@ public class JsonFetcher {
return jsonObj;
}
public static ArrayList<String> readJsonAsString(String jsonFilePath) throws IOException {
ArrayList<String> jsonFileLines = new ArrayList<>();
Files.lines(
FileSystems.getDefault().getPath(jsonFilePath)
).forEach(jsonFileLines::add);
return jsonFileLines;
}
private static void readJsonFileAsString(String path) throws IOException {
Files.lines(
FileSystems.getDefault().getPath(path)

View File

@@ -1,58 +1,62 @@
== CHALLENGING, NOT PUNISHING https://www.youtube.com/watch?v=ea6UuRTjkKs
1. CONSISTENT RULES
- No arbitrary unstoppable death
== CHALLENGING, NOT PUNISHING == https://www.youtube.com/watch?v=ea6UuRTjkKs
2. Player's skill involved
- Can play around, not restart
1. CONSISTENT RULES
- No arbitrary unstoppable death
3. Usability of in-game tools
- Players should be able to 'regret' their strategy and adjust.
2. Player's skill involved
- Can play around, not restart
4. Comfortable control
3. Usability of in-game tools
- Players should be able to 'regret' their strategy and adjust.
5. Make players overcome the challenge, not defeating them
4. Comfortable control
6. Let players have "aha" moment when they failed.
- Make them hungry to retry with new strategies.
- Some small things they've could done differently
- e.g. "One-big-hit didn't worked, may I should've picked up high DPS one"
5. Make players overcome the challenge, not defeating them
6. Let players have "aha" moment when they failed.
- Make them hungry to retry with new strategies.
- Some small things they've could done differently
- e.g. "One-big-hit didn't worked, may I should've picked up high DPS one"
== MORE DEPTH, LESS COMPLEXITY https://www.youtube.com/watch?v=jVL4st0blGU
== MORE DEPTH, LESS COMPLEXITY == https://www.youtube.com/watch?v=jVL4st0blGU
1. Memorise less!
- Less burden to, even starting the game
- Start with gentle learning curve, getting slowly steep
- Intuitive UX (UI, control, ...)
- Good tutorial = lessens complexity
1. Memorise less!
- Less burden to, even starting the game
- Start with gentle learning curve, getting slowly steep
- Intuitive UX (UI, control, ...)
- Good tutorial = lessens complexity
2. Intuitive!
2. Intuitive!
3. Calculations per second
- reduce!
3. Calculations per second
- reduce!
4. Players have to know everything to even begin the play == FAIL (irreducible complexity)
- Make them get familiar with rules of the game
- Dwarf Fortress failed this!
4. Players have to know everything to even begin the play == FAIL (irreducible complexity)
- Make them get familiar with rules of the game
- Dwarf Fortress failed this!
== Lots of things players play with (aka don't make them bored)
== Lots of things players can play with (aka don't make them bored) ==
- Combat, battle, building, mechanics, adventure, dungeon explore, spelunking
- Not scaled; easy combat, tough combat, tedious combat, etc.
== Achieving perfect imbalance https://www.youtube.com/watch?v=e31OSVZF77w
== Achieving perfect imbalance == https://www.youtube.com/watch?v=e31OSVZF77w
- Make sure no matter how you skilled, your playable character cannot be good at everything
- Give players __wide pool of options__ to solve problem
(kill the boss, defend their adobe, fast transportation, etc.)
##*=- What feeling do you want to convey to the player?
-=*## What feeling do you want to convey to the player? ##*=-
== Always think WHY would you want to add _something_ on the game
== Always think WHY would you want to add _something_ on the game ==
- e.g. Why you are adding RPG leveling system?
@@ -60,104 +64,69 @@
See also:
HEARTS, CLUBS, DIAMONDS, SPADES: PLAYERS WHO SUIT MUDS
====================================
* Friendlier version of Dwarf Fortress Adventure mode
- Yet _lots of fun_
- Add Fortress mode features by 'make your own settling'
- Hard to actually die, but once you die, you're done.
+ Config: imtooyoungtodie for easy mode
== Friendlier version of Dwarf Fortress Adventure mode ==
- Genre: Adventure, Open world (towns in RPG, building, town managing (conquer existing one or
you build one and persuade existing people to move in) -> See Dwarf Fortress and Animal Crossing)
- Yet _lots of fun_
- Add Fortress mode features by 'make your own settling'
- Hard to actually die, but once you die, you're done.
+ Config: imtooyoungtodie for easy mode
- Genre: Adventure, Open world (towns in RPG, building, town managing (conquer existing one or
you build one and persuade existing people to move in) -> See Dwarf Fortress and Animal Crossing)
* Adventure: adventure this vast—5,5 km wide—world, discover new (and good/horrible) things
* Open world:
- Building: building your own houses, structures, etc.
- Town managing:
1. Build your own little hamlet and manage it
or-
2. Conquer existing one and become a ruler
The town is a special hamlet that can be tailored for your taste
- Survival:
mobs will trying to attack your assets (yourself, your hamlet, your people)
== Side view ==
* Adventure: adventure this vast—5,5 km wide—world, discover new (and good/horrible) things
== Interact menu w/ mouse right ==
* Open world:
- Building: building your own houses, structures, etc.
- Town managing:
1. Build your own little hamlet and manage it
or-
2. Conquer existing one and become a ruler
The town is a special hamlet that can be tailored for your taste
- Survival:
mobs will trying to attack your assets (yourself, your hamlet, your people)
* Side view
* Interact menu w/ mouse right
* Pixelated sprites
== Pixelated sprites ==
- Use 2x sprites if rotating does not work well
== User experience ==
### User experience ###
* Indicative mouse cursor
* Indicative mouse cursor
== Game mechanics ==
### Game mechanics ###
* 24 pixels == 1 metre
* 24 pixels == 1 metre
== Purpose of the game ==
### Purpose of the game ###
* Boss
- Will be mentioned/shown as absolute _evil_.
- But actually is not.
* Theme
- Is an evil really really is what we think?
- Is there a thing as 'absolute evil'?
* Boss character
- From debugger character
- Name key: "Sigriðr hinn Dróttningin" (can be changed)
* Little setting
- A ruler, hated by people
* Mechanics
- Beating boss does not ends the game, but grants an ability to
create new character as it.
### Making sprite ###
* Layers
- (Optional) Hair foreground
- Right arm dress
- Right arm body
- Dress
- Boot right
- Boot left
- Body
- (Optional) Hair accessory
- Hair
- Head
- Left arm dress
- Left arm body
- (Optional) SFX
* Size
- Regular sprite 'height' (hitbox height) : 40 px
- Apparent height may vary
### Chargen ###
* Select hair, colours, then compile them into single spritesheet
* NO gender distinction, but have masculine/neutral/feminine designs (in clothing, hairstyles, etc.)
* Colour: 4096 colours (12-bit 0x000 - 0xFFF)
* Base mass: 60 kg
* Boss
- Will be mentioned/shown as absolute _evil_.
- But actually is not.
* Theme
- Is an evil really really is what we think?
- Is there a thing as 'absolute evil'?
* Boss character
- From debugger character
- Name key: "Sigriðr hinn Dróttningin" (can be changed)
* Little setting
- A ruler, hated by people
* Mechanics
- Beating boss does not ends the game, but grants an ability to
create new character as it.

View File

@@ -24,11 +24,11 @@ public class Player extends ActorWithBody implements Controllable, Pocketed, Fac
int jumpCounter = 0;
int walkPowerCounter = 0;
private final int MAX_JUMP_LENGTH = 20;
private final int MAX_JUMP_LENGTH = 15;
/**
* experimental value.
*/
private final float JUMP_ACCELERATION_MOD = 92f / 10000f;
private final float JUMP_ACCELERATION_MOD = 180f / 10000f;
private final int WALK_FRAMES_TO_MAX_ACCEL = 6;
public float readonly_totalX = 0, readonly_totalY = 0;

View File

@@ -1,45 +1,96 @@
* Weapon tier
== Weapon tier ==
Natural / Common Stone -> Copper -> Iron -> Silver -> Titanium
Forging --------------> Steel --------^
Exotic ('elven') Glass Aurichalcum
Special (something 'adamant') ??? (Use material spec of CNT, tensile strength 180 GPa)
Natural / Common Stone -> Copper -> Iron -> Silver -> Titanium
Forging --------------> Steel --------^
Exotic ('elven') Glass Aurichalcum
Special (something 'adamant') ??? (Use material spec of CNT, tensile strength 180 GPa)
= Metal graphics
- Gold: Hue 43, low Saturation
- Aurichalcum: Hue 43, mid-high Saturation
- Copper: Hue 33,
- Copper rust: Hue 160
- Iron rust: Hue 21
* Metal graphics
== Size variation ==
Gold: Hue 43, low Saturation
Aurichalcum: Hue 43, mid-high Saturation
Copper: Hue 33,
Copper rust: Hue 160
Iron rust: Hue 21
Race base weapon/tool size <- 10 [kg]
Size tolerance <- (50% * str/1000), or say, 20%
If the size is bigger than tolerable, weapon speed severely slows down, tools become unusable
if use time >= 0.75 second, the weapon/tool cannot be equipped.
Small weapons/tools gains no (dis)advantage
When drawing: scale by (craftedWeaponSize / baseWeaponSize)
Crafted tool/weapon size is dependent to the baseRaceMass.
* Size variation
== Gemstone tier ==
Race base weapon/tool size <- 10 [kg]
Size tolerance <- (50% * str/1000), or say, 20%
If the size is bigger than tolerable, weapon speed severely slows down, tools become unusable
if use time >= 0.75 second, the weapon/tool cannot be equipped.
Small weapons gains no (dis)advantage, tools become unusable
Crafted tool/weapon size is dependent on the baseRaceMass.
Topaz -> R·G·B -> Diamond·Amethyst
* Gemstone tier
== Colouring ==
Topaz -> R·G·B -> Diamond·Amethyst
* Colouring
Natural: Use 4096
Magical/Surreal: Use 24 Bits
Natural: Use 4096
Magical/Surreal: Use 24 Bits
= Colouring of potion
- Randomised, roguelike fashion
- Choose Col(R40, G40, B40) from set of finite cards:
39, 39, 19, 19, 0, 0
- MULTIPLY blend chosen colour with white texture
- MULTIPLY blend chosen colour with white texture
== Roguelike identity ==
= Randomised things
- E.g. potion
Lime-coloured potion
First play: "Potion (???)"
After drank: "Potion (Healing)" is revealed.
Second (new) play: "Potion (???)"
After drank: "Potion (Neurotoxin)" is revealed.
== Making sprite ==
* Layers
- (Optional) Glow
- (Optional) Hair foreground
- Right arm dress
- Right arm body
- Dress
- Boots
- Body
- (Optional) Hair accessory
- Hair
- Head
- Left arm dress
- Left arm body
- (Optional) SFX
* Size
- Regular sprite 'height' (hitbox height) : 40 px
- Apparent height may vary
== Chargen ==
* Select hair, colours, then compile them into single spritesheet
* NO gender distinction, but have masculine/neutral/feminine looks (in clothing, hairstyles, etc.)
* Colour: 4096 colours (12-bit 0x000 - 0xFFF)
* Base mass: 60 kg
== Custom pattern making ==
- Players can create their own décors (hang on wall), dresses.
- Two looms (216 colour mode, 4096 colour mode)

View File

@@ -1,4 +0,0 @@
* Drawing
- Players can create their own décors (hang on wall), dresses.
- Two looms (216 colour mode, 4096 colour mode)

View File

@@ -184,63 +184,68 @@ public class MapCamera {
int thisTerrainTile = map.getTileFromTerrain(x, y);
// draw
if (
try {
if (
(
( // wall and not blocked
(mode == WALL) && isWallThatBeDrawn(x, y)
)
||
(mode == TERRAIN)
) // not an air tile
&& (thisTile > 0)
&&
// check if light level of upper tile is zero and
// that of this tile is also zero
(((y > 0)
&& !((LightmapRenderer.getValueFromMap(x, y) == 0)
&& (LightmapRenderer.getValueFromMap(x, y - 1) == 0))
)
||
// check if light level of this tile is zero, for y = 0
((y == 0)
&& (LightmapRenderer.getValueFromMap(x, y) > 0)
))) {
(
( // wall and not blocked
(mode == WALL) && isWallThatBeDrawn(x, y)
)
||
(mode == TERRAIN)
) // not an air tile
&& (thisTile > 0)
&&
// check if light level of upper tile is zero and
// that of this tile is also zero
(((y > 0)
&& !((LightmapRenderer.getValueFromMap(x, y) == 0)
&& (LightmapRenderer.getValueFromMap(x, y - 1) == 0))
)
||
// check if light level of this tile is zero, for y = 0
((y == 0)
&& (LightmapRenderer.getValueFromMap(x, y) > 0)
))) {
int nearbyTilesInfo;
//if (thisTile == DIRT) {
// nearbyTilesInfo = getGrassInfo(x, y, GRASS);
//}
//else {
// nearbyTilesInfo = getNearbyTilesInfo(x, y, AIR);
//}
int nearbyTilesInfo;
//if (thisTile == DIRT) {
// nearbyTilesInfo = getGrassInfo(x, y, GRASS);
//}
//else {
// nearbyTilesInfo = getNearbyTilesInfo(x, y, AIR);
//}
if (isDarkenAir((byte) thisTile)) {
nearbyTilesInfo = getNearbyTilesInfo(x, y, mode, AIR);
}
else if (isConnectSelf((byte) thisTile)) {
nearbyTilesInfo = getNearbyTilesInfo(x, y, mode, thisTile);
}
else {
nearbyTilesInfo = 0;
}
if (isDarkenAir((byte) thisTile)) {
nearbyTilesInfo = getNearbyTilesInfo(x, y, mode, AIR);
}
else if (isConnectSelf((byte) thisTile)) {
nearbyTilesInfo = getNearbyTilesInfo(x, y, mode, thisTile);
}
else {
nearbyTilesInfo = 0;
}
int thisTileX = nearbyTilesInfo;
int thisTileY = thisTile;
int thisTileX = nearbyTilesInfo;
int thisTileY = thisTile;
if (drawModeTilesBlendMul) {
if (isBlendMul((byte) thisTile)) {
if (drawModeTilesBlendMul) {
if (isBlendMul((byte) thisTile)) {
drawTile(mode, x, y, thisTileX, thisTileY);
}
}
else {
// currently it draws all the transparent tile and colour mixes
// on top of the previously drawn tile
// TODO check wether it works as intended when skybox is dark
// add instruction "if (!isBlendMul((byte) thisTile))"
drawTile(mode, x, y, thisTileX, thisTileY);
}
}
else {
// currently it draws all the transparent tile and colour mixes
// on top of the previously drawn tile
// TODO check wether it works as intended when skybox is dark
// add instruction "if (!isBlendMul((byte) thisTile))"
drawTile(mode, x, y, thisTileX, thisTileY);
}
}
catch (NullPointerException e) {
// do nothing. This exception handling may hide erratic behaviour completely.
}
}
}

View File

@@ -13,6 +13,8 @@ public class RoguelikeRandomiser {
private static final int[] POTION_PRIMARY_COLSET = {15, 15, 8, 8, 0, 0};
private static Hashtable<Integer, Col4096> potionColours;
private static Hashtable<Col4096, Boolean> coloursDiscovered;
private static ArrayList<Col4096> coloursTaken;

View File

@@ -1,13 +1,16 @@
package com.Torvald.Terrarum;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.Torvald.ImageFont.GameFontBase;
import com.Torvald.ImageFont.GameFontWhite;
import com.Torvald.Terrarum.ConsoleCommand.Authenticator;
import com.Torvald.JsonFetcher;
import com.Torvald.Terrarum.LangPack.Lang;
import org.lwjgl.input.Controllers;
import org.newdawn.slick.*;
@@ -146,14 +149,14 @@ public class Terrarum extends StateBasedGame {
}
private static void createFiles() throws IOException {
File[] files = {
new File(defaultDir + "/properties")
};
File configFile = new File(defaultDir + "/config.json");
for (File f : files){
if (!f.exists()){
f.createNewFile();
}
if (!configFile.exists() || configFile.length() == 0) {
configFile.createNewFile();
ArrayList<String> jsonLines = JsonFetcher.readJsonAsString("./res/config_default.json");
PrintWriter printWriter = new PrintWriter(configFile);
jsonLines.forEach(printWriter::println);
printWriter.close();
}
}
}