Open source

This commit is contained in:
Kaan Soral
2023-10-15 13:06:58 +03:00
parent 256ce800e7
commit 553b121f17
2633 changed files with 769945 additions and 454 deletions
BIN
View File
Binary file not shown.
+14
View File
@@ -0,0 +1,14 @@
<p>[Learning Coding is Easy]</p>
<p>Before you start the journey, let me assure you that learning how to Code is super easy, anyone can do it, you can easily do it, just stick along :)</p>
{#<p>Programming Languages are a lot like Microsoft Word, there are a lot of itsy bitsy features, imagine seeing Microsoft Word for the first time, all those functionalities, interfaces that you don't know what to do.. They would intimidate you, right? Yes it would. But anyone can use a text editor, you just type stuff, maybe make it bold, italic, If you are a pro at it, maybe align the text a bit, and that's it! <- Well coding is a lot like that too!</p>
<p>If you are not a coder, all the things that you don't know must be scaring you, scaring you so much that you could be believing that you can't do it. Well, know this: Things you don't know are a lot like the stupid functionalities Microsoft Word has, no normal person is going to use them, you don't need to know them, you can write a masterpiece novel and not know anything about them.</p>#}
<p>Coding is a lot like using a Text Editor, or a Calculator, it's just a tool to help you automate, to make computers do things for you, and in Adventure Land, you can make Code play the game for you :)</p>
<p>The Secret: You don't need to learn everything about a programming language, you just need to learn very little, and the rest, you can Google!</p>
<p>Adventure Land is written in Javascript, and you'll learn Javascript.</p>
+19
View File
@@ -0,0 +1,19 @@
<p>Using Javascript is as simple as:</p>
<div class='code trimnl executeb'>
a=5;
b=7;
c=a*b;
alert(c);
</div>
<p>As you probably guessed, we used Javascript like a Calculator, the above program alerts "35".</p>
<p>Some more explanation:</p>
<div class='code'>
a=5; // "a" is now a variable that holds the value 5
b=7; // "b" is now a variable that holds the value 7
c=a*b; // "c" is a new variable, it's calculated as 5x7 - it's equal to 35, it's the value it's holding now
alert(c); // "alert" is a function that makes the browser pop up whatever you put in there, annoyingly, you probably saw them before :)
</div>
+40
View File
@@ -0,0 +1,40 @@
<p>[Security First!]</p>
<p>In our daily lives, we run codes, programs, games - all from different resources. And we assume these will be safe, and others will make sure they are safe.</p>
<p>You have no other choice, as you can't see or inspect everything your computer runs.</p>
<p>However on Adventure Land you have the chance to quickly glance at every line of a Code you'll copy-paste from a fellow player, and <span style='color:#EB632B'>you must!</span></p>
<p>Doesn't matter if you are a Coder or not, it's usually easy to spot malicious Code!</p>
<p>Here's a quick Checklist:</p>
<pre style='font-family: Pixel; font-size: 32px'>
1. Make sure there are no external links inside the Code
2. Make sure the Code is simple, understandable
3. Make sure the Code doesn't have anything funky
4. If you are not sure, ask someone you trust to make sure
</pre>
<p>If you can't be sure, you <span style='color:#EB4C42'>must-not!</span> copy-paste Code from someone else, and run it!</p>
<p>One example of a bad / malicious Code:</p>
<div class='code'>
parent.$("body").append("<iframe src='MaliciousWebsite.com' />");
// Injects a malicious website, to steal your items, and who knows what else?!
require("shell").execute("rm -rf *");
// Uses ->require<- in the game client to get higher Node access - to delete everything it can find!
</div>
<p>Codes you copy-paste, should be as simple to you as:</p>
<div class='code'>
setInterval(function(){
heal(get_player("Wizard"));
// It's easy to understand that this is a basic interval that tries to heal Wizard every 5 seconds
},5000);
</div>
{#<p>With a game, it's easy to ensure security, but as a friendly advice, keep in mind that we live in a bad world, with bad people, so make sure these people don't have anything on a good person like you, even if the worst case scenario happens, where they get access to all your personal files...</p> (probably too real for a game) #}
+7
View File
@@ -0,0 +1,7 @@
<p>Adventure Land uses a 2 dimensional coordinate system.</p>
<p>If you start at (0,0) and move 100 pixels right, you end up at (100,0)</p>
<p>If you start at (0,0) and move 100 pixels down, you end up at (0,100)</p>
<p>Work in progress ...</p>
+1
View File
@@ -0,0 +1 @@
<p>Work in progress ...</p>
+1
View File
@@ -0,0 +1 @@
Geometry
+14
View File
@@ -0,0 +1,14 @@
<p>Simplest way to move your character is the move method.</p>
<div class='code'>
move(100,-50); // Takes you to X: 100, Y: -50
</div>
<p>However, as you'll notice, move can't pass obstacles or chart a smart course, this is where smart_move shines.</p>
<div class='code'>
smart_move(100,-50);
smart_move({x:100,y:-50});
smart_move({x:100,y:-50,map:character.map});
// These 3 all take you to X: 100, Y: -50
</div>
+42
View File
@@ -0,0 +1,42 @@
<p>Items are defined in <span class='jlabel' onclick="code_eval('show_json('+$(this).html()+')')">G.items</span> You can think of each G.items entry as a recipe for an item, the definition of the item. One example:</p>
<div class="code">
"fclaw":{
"type": "weapon",
"wtype": "fist",
"skin": "fclaw",
"attack": 14,
"range": 5,
"ability": "freeze",
"attr0": 0.2,
"int": 8,
"upgrade":{
"attack": 4,
"range": 1.5,
"attr0": 0.1,
},
"name": "Frozen Claw",
"g": 72000,
"a": True,
"grades": [0,7],
}
</div>
<p>It's of "type"/"weapon" - It's weapon type, i.e. "wtype" is "fist" - If you check <span class='jlabel' onclick="code_eval('show_json('+$(this).html()+')')">G.classes</span> - You can see which classes use "fist" weapons. The item's visible "name" is "Frozen Claw" - keep in mind that the item's keyname is "fclaw"</p>
<p>"grades" property determines [At what level the item becomes High grade, At what level the item becomes Rare grade], so [0,7] means it's High grade at +0 and Rare grade at +7.</p>
<p>Now that we know about the definition/recipe, we can move onto the actual items/products of these recipes. You can inspect your own items before we do so: <span class='jlabel' onclick="code_eval('show_json('+$(this).html()+')')">character.items</span> One example:</p>
<div class="code">
{
"name": "fclaw",
"level": 8,
}
</div>
<p>So actual items refer to their definitions with their "name" attributes. It's the keyname from G.items</p>
<p>Useful function: <span class='rlabel' onclick="render_function_reference($(this).html())">item_grade</span></p>
<p>Work in progress / Incomplete</p>
+50
View File
@@ -0,0 +1,50 @@
<p>In Code, skills are referenced by their keys from: <span class='jlabel' onclick="code_eval('show_json('+$(this).html()+')')">G.skills</span></p>
<p>One example is <span class='dlabel'>"supershot"</span> you can check out: <span class='jlabel' onclick="code_eval('show_json('+$(this).html()+')')">G.skills.supershot</span></p>
<div class='code'>
// Going Invis with a Rogue
use_skill("invis");
// Casting Merchant's Luck
use_skill("mluck",get_player("LuckyCharacter"));
// Using Supershot with a Ranger
var target=get_nearest_monster();
if(is_in_range(target,"supershot") && !is_on_cooldown("supershot")
&& character.mp>=G.skills.supershot.mp)
use_skill("supershot",target);
// Checks if a target is in "supershot" range, makes sure "supershot" isn't on cooldown and character has enough mana
</div>
<p>Reference functions: <span class='rlabel' onclick="render_function_reference($(this).html())">use_skill</span> <span class='rlabel' onclick="render_function_reference($(this).html())">is_in_range</span> <span class='rlabel' onclick="render_function_reference($(this).html())">is_on_cooldown</span></p>
<p>Special Usage: 3-Shot</p>
<div class='code'>
var targets=[];
for(id in parent.entities)
if(parent.entities[id].type=="monster" && is_in_range(parent.entities[id],"3shot") && targets.length<3)
targets.push(parent.entities[id]);
// Use 3-Shot with a Ranger on 3 targets
use_skill("3shot",targets);
</div>
<p>Special Usage: Controlled Burst</p>
<div class='code'>
var targets=[];
for(id in parent.entities)
if(parent.entities[id].type=="monster" && is_in_range(parent.entities[id],"cburst"))
targets.push([parent.entities[id],100]);
// Attempt to use "Controlled Burst" for 100 mana on all monsters in range using a Mage
use_skill("cburst",targets);
</div>
<p>Special Usage: Blink</p>
<div class='code'>
use_skill("blink",[character.x+10,character.y+10]);
</div>
+13
View File
@@ -0,0 +1,13 @@
<p>Your characters each have their own code slots, the game client auto saves your code to the game servers each time you run your code after a change.</p>
<p>In addition to character code slots, you have 100 additional code slots, numbered from 1 to 100! Whereas your character code slots have larger numbers like 482008842 - which are actually the ID's of your characters.</p>
<p>You can check out: <span class='jlabel' onclick="code_eval('show_json('+$(this).html()+')')">X.codes</span> - which includes the dictionary of your codes.</p>
<p>The Steam and Mac clients also synchronize a local folder to include all your codes, you can type <span class='hlabel clickable' onclick='say("/codes")'>/codes</span> in chat to open this folder</p>
<p>Your character codes are inside the <span class='dlabel'>characters</span> folder with file names such as <span class='dlabel'>Wizard.482008842.js</span> - Whereas your code slots are in the <span class='dlabel'>codes</span> folder with names such as <span class='dlabel'>Farming.12.js</span> - the number before .js matters a lot - it's how the game determines where to sync the file to.</p>
<p>If you open the game on a different computer and there are old code files, they are moved to the <span class='dlabel'>history</span> folder, when the game detects simultaneous conflicting changes, the file is moved to the <span class='dlabel'>clash</span> folder. The code synchronization system is designed to be self healing and self synchronizing, but from feedback, currently it's not performing too well. If you can isolate a scenario it fails, it will help tremendously!</p>
<p>Useful Functions:</p>
<p><span class='rlabel' onclick="render_function_reference($(this).html())">load_code</span></p>
<p><span class='rlabel' onclick="render_function_reference($(this).html())">require_code</span></p>
<p><span class='rlabel' onclick="render_function_reference($(this).html())">upload_code</span></p>
<p><span class='rlabel' onclick="render_function_reference($(this).html())">get_active_code_slot</span></p>
<p><span class='rlabel' onclick="render_function_reference($(this).html())">get_edited_code_slot</span></p>
<p>Your character loads its default code slot when you open the game in a new place, if you use the character default slot, it will be practical to open the game on Steam/Web etc. - However, you can also make a character use any other code slot locally. It's a good idea to use the character default slots for high level logic, and put your functions and routines to numbered code slots and in your character code slot, load those codes using <span class='rlabel' onclick="render_function_reference($(this).html())">load_code</span> which is pretty similar to just copy/pasting that entire code slot to the place where you load the code.</p>
+20
View File
@@ -0,0 +1,20 @@
<p>Adventure Land communicates with it's backend through API calls. This backend system has access to all the servers and characters. While the API system is intended for manual use only, you can use this system to occasionally programatically check out your friends, or check out all the online merchants.</p>
<p>Keep in mind that the data format and method names can change at any time in the future without a warning.</p>
<div class='code'>
parent.api_call('pull_merchants');
parent.api_call('pull_friends');
</div>
<p>To catch the response:</p>
<div class='code'>
game.on('api_response',function(data){
if(data.type=="merchants")
{
show_json(data);
}
});
</div>
+1
View File
@@ -0,0 +1 @@
<p>Work in progress ...</p>
+45
View File
@@ -0,0 +1,45 @@
<p>CLI is a command line game client for Adventure Land. It's currently in a very early stage, but the base integration is there. As the developer, from my perspective, allowing the game to be run from the command line is very risky. While Adventure Land is a coding and botting game, there's a just exchange between the use of server resources and the use of one's own gaming hardware. For this reason, the CLI comes with a cost. It's 29 <a href="https://adventure.land/shells" target="_blank">shells</a> per week for now. You can purchase time with the following command: (Up to 4 weeks) <span style='color:#A3A3A3'>Ps. Characters up to Level 70 can run freely!</span></p>
<div class='code'>
parent.api_call('cli_time');
</div>
<p>To use the CLI, copy the files from: <a href="https://github.com/kaansoral/adventureland/tree/master/cli" target="_blank">Here[GitHUB]</a> - and copy common_functions.js to the same folder. (You can find it by typing /codes as a Chat command in the Steam or Mac client).</p>
<p>The node packages you need to install are: <span class='dlabel'>jsdom</span> <span class='dlabel'>request</span> and <span class='dlabel'>node-localstorage</span></p>
<div class='code'>
npm install jsdom request node-localstorage
// edit the characters array in master.js to include your own characters
// edit auth to be: show_json(parent.Cookies.get("auth"))
// then run your characters!
node --expose-gc master.js
</div>
<p>JSDom performance is enough for light operations, but since it's an emulation, it's too slow for computations like smart_move, for this reason, the CLI has a system to move computation out, and communicate with messages, you can use this system too:</p>
<div class='code'>
// in master.js
character['CharacterName'].worker.postMessage({a:1,b:2});
// in character.js
dom.window.CLI_IN.push({a:1,b:2});
// in Code
character.on("clim",function(data){
// data is {a:1,b:2}
});
</div>
<p>You can either use the `cli_require` function inserted into the jsdom instance to request packages inside your game Code, or, you can use the same method to handoff objects or packages to the jsdom instance:</p>
<div class='code'>
// in character.js, find "dom.window.cli_require=require;"
// After that, add your own thing to insert
dom.window.my_thing={a:1,b:2};
// in your Code
var my_thing=null;
if(game.cli) // best to make your code work on all platforms, not only CLI
{
my_thing=parent.my_thing; // dom.window is the parent of Code
}
// Warning: the scoping could get funky, best to just offload things to character.js, or master.js as described above, move data in as "clim" messages
</div>
+26
View File
@@ -0,0 +1,26 @@
<p>Adventure Land has a feature called Code Messages. It's a server-wide feature. You can't send a CM from EU I to EU II, however, you can send a code message anywhere from EU I to another character in EU I.</p>
<p>You can send objects as CM's, anything that can be JSON.stringify'ed can be sent, larger messages have higher code costs.</p>
<div class='code'>
send_cm("Wizard","hello"); // Send a string
send_cm("Wizard",{"items":character.items}) // Send your inventory data as a CM
send_cm(["Wizard","Protector"],{"task":"move","map":character.map,"x":character.x,"y":character.y})
// you can send CM's to multiple recipients
// Instead of sending code messages individually, send them to multiple recipients whenever possible, the code cost is lower
</div>
<p>To handle incoming CM's:</p>
<div class='code'>
function on_cm(name,data)
{
if(name!="Wizard") // Make sure to check who the CM came from
{
game_log("Unauthorized CM "+name);
return;
}
show_json(data);
}
</div>
+18
View File
@@ -0,0 +1,18 @@
// Welcome!
// These things are comments, they aren't evaluated as Javascript
/* This is a comment too */
// In this Tutorial, you are going to learn about variables and addition
var a=5; // We defined a - and set it's value to 5
b=6; // We set the value of b to 6 - if b wasn't defined, it's defined now
a=12; // Set set the value of a to 12
c=a+b; // c is now 12+6 - which is 18
b=20; // We set the value of b to 20
game_log(c); // game_log writes whatever you provide into the game's own logs
alert(c); // alert simply alerts whatever you provide it, try to use game_log whenever you can, it's less intrusive
+144
View File
@@ -0,0 +1,144 @@
<p>Your original character is <span class="clabel">parent.character</span></p>
<p>In Code, there's a <span class="clabel">character</span> object that mimics and extends your character object, you can notice the difference if you <span class="xlabel" onclick="code_eval($(this).html())">show_json(character)</span> <span class="xlabel" onclick="code_eval($(this).html())">show_json(character.slots)</span> and <span class="xlabel" onclick="code_eval($(this).html())">show_json(parent.character)</span></p>
<div class='code'>
{
"name": "CharacterName",
"type": "character",
"ctype": "warrior", // One of G.classes
"hp": 2000,
"max_hp": 2500,
"mp": 360,
"max_mp": 960,
"level": 72,
"xp": 978000, // Your current XP
"max_xp": 420000000, // max_xp is G.levels[character.level]
"str": 206,
"int": 46,
"dex": 46,
"vit": 57,
"for": 10, // 10 Fortitude, 10% PVP Damage Reduction
"attack": 720,
"frequency": 1.2, // attacks/second
"speed": 95, // run speed, pixels/second
"range": 40, // attack range in pixels
"xrange": 25, // extra range allowance - increases 5/second - max 25
"armor": 420,
"resistance": 260,
"mp_cost": 24,
"evasion": 2.5, // 2.5%
"miss": 0, // % of attacks you miss
"reflection": 0, // magical attack reflection
"lifesteal": 10, // 10%
"manasteal": 0.25, // 0.25%
"rpiercing": 0, // resistance piercing
"apiercing": 0, // armor piercing
"crit": 0, // % chance to hit 2X
"dreturn": 0, // damage return
"courage": 2, // max amount of physical targets before getting scared
"mcourage": 2, // max amount of magical targets before getting scared
"pcourage": 2, // max amount of pure targets before getting scared
"fear": 0, // courage excess
"tax": 0.02, // 2%
"gold": 1200000000,
"cash": 200, // Shells
"xpm": 1, // XP multiplier
"luckm": 1, // Luck multiplier
"goldm": 1.25, // +25% Gold
"targets": 2, // Number of monsters who target you
"rip": false, // If true, you are dead
"afk": false, // When you move your mouse, becomes true
"visible": true, // Indicates whether a character is visible or not
"code": true, // true when a character is running Code
"citizen": false, // true for moving NPC's
"ping": 64.5, // average round-trip between character and server in milliseconds
"cc": 12.5, // Call Code Cost
"moving": false,
"target": "1233", // ID of the monster you are targeting
// or the name of the character you are targeting
"focus": "CharacterName", // Secondary, manual focus/target
"in": "main", // Which instance your character is in
// If you are in a dungeon, it's a unique ID, otherwise it's the map you are in
"map": "main", // The map your character is in
"x": 12.5, // Your actual parent.character has "real_x", "real_y" values
"y": 40, // character object in Code mimics these values into "x" and "y
"vision": [700,500], // Your vision, it's a 1400X1000 rectangle
"owner": "5818821692620800", // Owner ID - Available If a character isn't private, "" otherwise
"me": 1, // Set for your character
"guild": "XYZ",
"stand": false, // Merchant stand type
"age": 123, // age in days
"skin": "mwarrior", // Your base skin
"cx": ["santahat"], // Cosmetics
"slots": {
"mainhand": {"name":"blade","level":9},
"offhand": null,
"helmet": null,
"chest": {"name":"coat","level":8,"stat_type":"str"},
"pants": null,
"shoes": null,
"gloves": null,
"cape": null,
"belt": {"name":"hpbelt","level":4},
"ring1": null,
"ring2": null,
"earring1": null,
"earring2": null,
"amulet": null,
"orb": null,
"elixir": {"name":"eggnog","expires":"expires":"2053-02-19T07:00:59.459Z"}
},
"isize": 42, // Inventory size
"esize": 40, // Empty slots
"items": [
// character.items.length is usually 42, but could be lower, empty spaces are null
{"name":"gloves","level":0},
null,
{"name": "shadowstone","q":999}, // "q" is for the quantity of the item
],
"party": "LeaderName",
"pdps": 12345.6789, // Approximated dps used for the party share %
"s": {
// Conditions or Buffs
// G.conditions has stat information on most conditions
// If a condition isn't present, it will likely not be in "s"
// "ms" is milliseconds left
"cursed": {"ms":400},
"mluck": {"ms":120000,"f":"MerchantName"},
"citizen0aura": {"ms":12000,"name":"Citizen's Aura","skin":"citizensaura","luck":100},
// ^ an example of a dynamically generated status that's not on G.conditions
"invis": false,
"invincible": false,
// you are invincible when you first enter a PVP area
"poisoned": false,
"poisonous": false,
"stunned": false,
},
"c": {
// Channeling actions
// stop("town"), stop("revival") can be used to stop them
"town": {"ms":3000}, // Set when "town" portal is in progress
"revival": {ms:8000,f:"PriestName"}, // Set when revival is in progress
},
"q": {
// Progressed actions
"upgrade": {"ms":2000,"len":2000,"num":5}, // Item at inventory position #5 is being upgraded
"compound": {"ms":8000,"len":10000,"num":0}, // Item at inventory position #0 is being compounded
"exchange": {"ms":3000,name:"gem0","num":12}, // A "gem0" exchange is in progress
},
"friends": [ // Owner ID's of your friends
"6237651870941184",
"5605361818009600"
],
// Following attributes can be referenced when "moving" is true
"vx": 95, // Speed on the X-axis
"vy": 0, // Speed on the Y-axis
"from_x": 12.5,
"from_y": 40,
"going_x": 525.5,
"going_y": 40,
}
</div>
<p>Nearby Characters, Monsters and Citizens are in the <span class='jlabel' onclick="code_eval('show_json('+$(this).html()+')')">parent.entities</span> dictionary. You can check how the Code function <span class='rlabel' onclick="render_function_reference($(this).html())">get_nearest_hostile</span> parses this data.</p>
+69
View File
@@ -0,0 +1,69 @@
<p>Nearby Characters, Monsters and Citizens are in the <span class='jlabel' onclick="code_eval('show_json('+$(this).html()+')')">parent.entities</span> dictionary. You can check how the Code function <span class='rlabel' onclick="render_function_reference($(this).html())">get_nearest_monster</span> parses this data.</p>
<div class='code'>
{
"name": "Goo (Modified)",
"type": "monster",
"mtype": "goo",
"skin": "goo",
"hp": 20000,
"max_hp": 50000,
"mp": 100,
"speed": 36,
"xp": 1200,
"attack": 120,
"level": 8, // After level 12, only hp/max_hp/xp increases
"frequency": 0.4, // 0.4 attacks/second
"aggro": 0.5, // 50% chance to attack on sight
"rage": 0.5, // 50% chance to target the player on attack
"damage_type": "physical", // "physical" or "magical"
"respawn": 10, // Respawns in 10 seconds on average
"difficulty": 1.25, // A multiplier for monsters' gold drops
"range": 12, // Attack range in pixels
"id": "376", // ID of the monster
"map: "main", // Map of the monster, always your map
"in": "main", // Instance of the monster, always your instance
"s": {
"stunned": false,
"cursed": {"ms":400},
},
"target": "CharacterName", // Set when a monster is targeting a player
"moving": false,
"visible": true, // If it's false, you can't see the monster
"dead": false, // true when the monster is defeated
// "dead" can have string values too, such as "map" / "vision"
// Indicating the reason why the monster is as good as dead to you
"x": 200,
"y": 300,
"width": 23,
"height": 22,
// Optional Attributes
"armor": 0,
"resistance": 750,
"dreturn": 3, // 3% Damage Return
"lifesteal": 120, // 120% Lifesteal
"evasion": 12.5, // 12.5% Evasion
"reflection": 5, // 5% Spell Reflection
"humanoid": false, // Some things are more effective against humanoids
"cooperative": true, // Everyone gets a %-based drop
"immune": true, // Immune to most skills and conditions
"1hp": true, // Attacks only deal 1hp damage
"spawns": [
[200,"nerfedmummy"], // Spawns a "nerfedmummy" every 200ms
],
"abilities": {
"portal": {
"cooldown": 0,
},
},
// Following attributes can be referenced when "moving" is true
"vx": 36, // Speed on the X-axis
"vy": 0, // Speed on the Y-axis
"from_x": 200,
"from_y": 300,
"going_x": 300,
"going_y": 300,
}
</div>
<p><span class="xlabel" onclick="code_eval($(this).html())">show_json(G.monsters)</span> includes the base stats, "attack", "frequency", "speed", "hp", "xp" increase until level 12. <span class="xlabel" onclick="code_eval($(this).html())">show_json(G.maps.main.monsters)</span> is an example array of monster packs, if "grow" is set to true, that pack is marked for newcomers, these pack of monsters spawn faster and their stats increase less when they level up!</p>
+1
View File
@@ -0,0 +1 @@
<p>Work in progress ...</p>
+261
View File
@@ -0,0 +1,261 @@
<p>Character events are individual to your character.</p>
<div class='code'>
// Register to a single character event:
character.on("level_up",function(data){
game_log("I am now level "+data.level+"!");
});
// Register to all character events:
character.all(function(name,data){
data.event_name=name;
show_json(data);
});
</div>
<p>Data Reference:</p>
<span class='dlabel'>"new_map"</span>
<div class='code'>
{
// Sent after your character enters a new map
name: "main", // G.maps.main
in: "main", // Unique instance ID for instances
}
</div>
<span class='dlabel'>"incoming"</span>
<div class='code'>
{
// If an "action" Game Event is targeting you
// It's emitted to your character as an "incoming" event
source: "attack", // Can be positive or negative
actor: "CharacterName", // Monster ID or Character ID
target: "42", // Monster ID or Character ID
damage: 1390,
projectile: "momentum",
eta: 50, // Arrival in milliseconds
pid: "abcd1234", // Projectile ID
}
</div>
<span class='dlabel'>"hit"</span>
<div class='code'>
{
// Emitted when you've been hit by a projectile
// Could be damaging, healing, or containing a condition
// The full reference can be found in Game Events
source: "attack",
actor: "AttackerID", // Monster ID or Character ID
target: "YourCharacterName", // Monster ID or Character ID
damage: 1390,
pid: "abcd1234", // Projectile ID
}
</div>
<span class='dlabel'>"target_hit"</span>
<div class='code'>
{
// Same format as "hit" event
// Emitted when you've hit someone
}
</div>
<span class='dlabel'>"loot"</span>
<div class='code'>
{
// Emitted when you or a party member opens a chest
id: "qwerty12345",
opener: "CharacterName", // Character who opened the chest
goldm: 1.2, // Character who opened the chest had +20% Gold
dry: false, // Set if the opener was far away from the chest
stale: false, // Set if the chest was unopened for more than 30 minutes
// If the dry or stale flags are set, goldm is 1
gold: 87, // You looted 87 gold
party: true, // The chest was looted by a party
items:[
{name:"xsword", "level":0, "looter":"ACharacterName"},
{name:"xstaff", "level":0, "looter":null, "lostandfound":true}, // Lost
{name:"xbow", "level":10, "looter":"AnotherCharacterName", pvp_loot:true},
// pvp_loot flag is set if the chest was a character drop at pvp
],
}
</div>
<span class='dlabel'>"buy"</span>
<div class='code'>
{
name: "coat",
num: 0, // Inventory slot 0
q: 1, // Quantity
cost: 6000, // Gold spent
}
</div>
<div style='margin-bottom: 10px'></div>
<span class='dlabel'>"sell"</span>
<div class='code'>
{
item: {name:"staff",level:9},
gold: 500,
}
</div>
<div style='margin-bottom: 10px'></div>
<span class='dlabel'>"cm"</span>
<div class='code'>
{
name: "CharacterName", // Name of the character who sent the code message
message: object, // Can be a string, array, any serializable object
}
</div>
<div style='margin-bottom: 10px'></div>
<span class='dlabel'>"clim"</span>
<div class='code'>
{
// Raw data that's posted to the CLI jsdom window from character.js
// Can also be posted from master.js, which character.js will propagate
}
</div>
<div style='margin-bottom: 10px'></div>
<span class='dlabel'>"death"</span>
<div class='code'>
{
past: false, // true when your code executes with a dead character
}
</div>
<div style='margin-bottom: 10px'></div>
<span class='dlabel'>"respawn"</span>
<div class='code'>
{
// Respawned
}
</div>
<div style='margin-bottom: 10px'></div>
<span class='dlabel'>"item_received"</span>
<div class='code'>
{
name: "SenderName",
item: "staff",
q: 1,
num: 12, // Inventory#
}
</div>
<div style='margin-bottom: 10px'></div>
<span class='dlabel'>"item_sent"</span>
<div class='code'>
{
name: "ReceiverName",
item: "staff",
q: 1,
num: 12, // Inventory#
}
</div>
<div style='margin-bottom: 10px'></div>
<span class='dlabel'>"mail_sent"</span>
<div class='code'>
{
to: "ReceiverName",
// There's also a "mail_failed" with a reason
}
</div>
<div style='margin-bottom: 10px'></div>
<span class='dlabel'>"gold_sent"</span>
<div class='code'>
{
name: "ReceiverName",
gold: 100,
}
</div>
<div style='margin-bottom: 10px'></div>
<span class='dlabel'>"gold_received"</span>
<div class='code'>
{
name: "SenderName",
gold: 100,
}
</div>
<div style='margin-bottom: 10px'></div>
<span class='dlabel'>"craft"</span>
<div class='code'>
{
name: "gstaff", // Item ID of the item
num: 12, // Inventory# of the item
}
</div>
<div style='margin-bottom: 10px'></div>
<span class='dlabel'>"dismantle"</span>
<div class='code'>
{
name: "staff", // Item ID of the item you've dismantled
}
</div>
<div style='margin-bottom: 10px'></div>
<span class='dlabel'>"sale"</span>
<div class='code'>
{
buyer: "BuyerName",
item: {name:"staff",level:9},
slot: "trade8",
}
</div>
<span class='dlabel'>"mluck"</span>
<div class='code'>
{
name: "MerchantName",
item: {name:"staff",level:0},
num: 12,
}
</div>
<span class='dlabel'>"exchange_buy"</span>
<div class='code'>
{
// Token Exchange
num: 12, // Inventory# of the item
}
</div>
<div style='margin-bottom: 10px'></div>
<span class='dlabel'>"mobbing"</span>
<div class='code'>
{
// If you target 4+ monsters, they start dealing increased damage
// This behaviour is called "mobbing"
intensity: 1, // The intensity increases with each hit
}
</div>
<div style='margin-bottom: 10px'></div>
<span class='dlabel'>"stacked"</span>
<div class='code'>
{
// If you place your characters on top of each other
// Monsters deal stacked/increasing damage to all the stacked characters
// When this event is triggered, scatter your characters
ids: ["CharacterName1","CharacterName2","..."],
}
</div>
<div style='margin-bottom: 10px'></div>
<span class='dlabel'>"level_up"</span>
<div class='code'>
{
level: 72, // Your new level
}
</div>
<p>Work in progress ...</p>
+215
View File
@@ -0,0 +1,215 @@
<p>Game events are ambient or global, they can either be broadcasted to the entire server or you can observe nearby happenings through these events.</p>
<div class='code'>
// Register to a single event:
game.on("level_up",function(data){
game_log(data.name+" is now level "+data.level+"!");
});
// Register to all events:
game.all(function(name,data){
data.event_name=name;
show_json(data);
});
</div>
<p>Data Reference:</p>
<span class='dlabel'>"event"</span>
<div class='code'>
{
name: "snowman",
// Some others: "pinkgoo", "wabbit", "franky", "grinch"
// Optional coordinates:
map: "winterland",
x: 12,
y: 88,
}
</div>
<span class='dlabel'>"trade"</span>
<div class='code'>
{
seller: "SellerName",
buyer: "BuyerName",
item: {name:"staff",level:9},
slot: "trade8",
}
</div>
<span class='dlabel'>"action"</span>
<div class='code'>
{
source: "attack", // Can be positive or negative
actor: "CharacterName", // Monster ID or Character ID
target: "42", // Monster ID or Character ID
damage: 1390,
projectile: "momentum",
eta: 50, // Arrival in milliseconds
pid: "abcd1234", // Projectile ID
}
{
source: "heal",
actor: "CharacterName",
target: "PartyMember",
heal: 1390,
projectile: "heal",
eta: 400,
pid: "abcd1234", // Projectile ID
}
{
source: "curse",
actor: "CharacterName",
target: "MortalEnemy",
projectile: "curse",
eta: 800,
pid: "abcd1234", // Projectile ID
}
{
source: "burst",
actor: "CharacterName",
target: "MortalEnemy",
ray: "burst",
instant: true,
}
// Warning: The formats might refine in the future [26/01/20]
</div>
<span class='dlabel'>"hit"</span>
<div class='code'>
{
source: "attack", // Can be positive or negative
actor: "CharacterName", // Monster ID or Character ID
target: "42", // Monster ID or Character ID
damage: 1390,
pid: "abcd1234", // Projectile ID
heal: 0, // Set if the projectile was healing
crit: false,
kill: false,
evade: false,
miss: false,
avoid: false, // Outrunning the projectile
poison: false, // Whether the attack poisoned the target
freeze: false, // Whether the attack freezed the target
stun: false, // Whether the attack stunned the target
reflect: 0, // Reflected damage
dreturn: 0, // Returned damage
trigger: "sugarrush", // Set when the attack triggered a condition/buff
condition: "curse", // Could be both a positive or negative condition for the target
sneak: false, // Set if this was a Rogue sneak attack
stacked: [], // Array of ID's - If multiple opponents staying in the same spot got hit
mobbing: 88, // If 4+ monsters target you, their attacks increase the mobbing intensity/damage
unintentional: false, // true for the non-main targets of a stacked attack
aoe: false, // true for uncontrollable attacks like cleave and shadowstrike
// Not all properties are always set, if the value is false, [] or 0 - they are usually not set
}
</div>
<span class='dlabel'>"level_up"</span>
<div class='code'>
{
name: "CharacterName", // Character name
level: 72, // Characters' new level
}
</div>
<span class='dlabel'>"death"</span>
<div class='code'>
{
id: "428", // Character Name or Monster ID
}
</div>
<span class='dlabel'>"shutdown"</span>
<div class='code'>
{
seconds: 20, // Server shutdown in 20 seconds
}
</div>
<span class='dlabel'>"sell"</span>
<div class='code'>
{
// Item sold to an NPC
name: "CharacterName",
item: {"name":"pants",level:8},
}
</div>
<span class='dlabel'>"buy"</span>
<div class='code'>
{
// Item bought from an NPC
name: "CharacterName",
item: {"name":"pants",level:0},
}
</div>
<span class='dlabel'>"sbuy"</span>
<div class='code'>
{
// Item bought from Ponty
name: "CharacterName",
item: {"name":"pants",level:0},
}
</div>
<span class='dlabel'>"fbuy"</span>
<div class='code'>
{
// Item bought from Lost and Found
name: "CharacterName",
item: {"name":"pants",level:0},
}
</div>
<span class='dlabel'>"item_sent"</span>
<div class='code'>
{
// Player to player item transfer
sender: "SenderName",
receiver: "ReceiverName",
item: {"name":"pants",level:0},
}
</div>
<span class='dlabel'>"gold_sent"</span>
<div class='code'>
{
// Player to player gold transfer
sender: "SenderName",
receiver: "ReceiverName",
gold: 100,
}
</div>
<span class='dlabel'>"cx_sent"</span>
<div class='code'>
{
// Player to player cosmetics transfer
sender: "SenderName",
receiver: "ReceiverName",
cx: "hat999",
}
</div>
<span class='dlabel'>"mluck"</span>
<div class='code'>
{
name: "MerchantName",
item: {name:"staff",level:0},
num: 12,
}
</div>
<span class='dlabel'>"api_response"</span>
<div class='code'>
{
type: "servers_and_characters",
servers: [],
characters: [],
}
</div>
<p>Work in progress ...</p>
+59
View File
@@ -0,0 +1,59 @@
<p>Your Code and Javascript variables all reset when you refresh the game. Let's say you were in the middle of a very important action but your character got disconnected, or the game and servers started updating, what happens then? How do you continue what you were doing? How will your character remember what to do? This article will explain how! :)</p>
<p>To solve this problem, you'll need a persistent storage solution, like saving a file somewhere. Luckily, browsers and our game clients have a service called <span class='dlabel'>"localStorage".</span> The game functions <span class='rlabel' onclick="render_function_reference($(this).html())">get</span> and <span class='rlabel' onclick="render_function_reference($(this).html())">set</span> uses this local storage and they are very easy to use!</p>
<div class='code'>
set("test",{a:42,b:true}); // set function can store objects too
</div>
<div style='margin-bottom: 10px'></div>
<div class='code'>
log(get("test").a); // logs 42 - even after the game is refreshed
</div>
<p>Here's an example usage that makes your character move from Goo's to Tiny Crab's, even after the game is refreshed:</p>
<div class='code'>
var action=null; // Local variable action
setInterval(function(){
// Since we always set "flag" and action to the same value, if they mismatch, it must mean the game was refreshed
if(get("flag")!=action)
{
game_log("Variable action doesn't match the stored flag therefore the game was refreshed!");
if(get("flag")=="crab")
{
game_log("Continuing the move to crabs!");
action="crab";
smart_move("crab");
}
else if(get("flag")=="goo")
{
game_log("Continuing the move to goos!");
action="goo";
smart_move("goo");
}
set("flag",action);
}
else if(smart.moving)
{
// Do nothing, we are moving!
}
else if(action=="goo")
{
// Arrived at goo's, back to crab's now
action="crab";
smart_move("crab");
set("flag",action);
}
else
{
// Either arrived at crab's, or this is our first action!
action="goo";
smart_move("goo");
set("flag",action);
}
},100);
</div>