flareteam / flare-engine Goto Github PK
View Code? Open in Web Editor NEWFree/Libre Action Roleplaying Engine (engine only)
Home Page: http://flarerpg.org/
License: GNU General Public License v3.0
Free/Libre Action Roleplaying Engine (engine only)
Home Page: http://flarerpg.org/
License: GNU General Public License v3.0
A very common problem when people are building Flare and trying to run it: all the game data (e.g. the flare/mods folder) is in the wrong location.
When we can't find any mod data at all (or can't find the mods.txt file, for example), let's print a longer message to stderr.
Something like this:
Fatal: Couldn't find the location of the Flare mods folder. Usually this means the game data was not correctly installed. Expected to find the data in the $XDG_DATA_DIRS path, in /usr/local/share/flare/mods, or in the same folder as the executable. Try placing the mods folder in one of these locations.
So I noticed MenuStash::add MenuInventory::add and ItemStorage::add
look very similar. About half the lines of code are exactly the same, the others only differ in
spacing, constants or other class specific limits.
Would it make sense to refactor all of these storage classes to use a common code base?
We merged the three campaign mods (frontier, averguard, living_bones) into alpha_demo. My local config mods.txt file still has those old mods though.
When I tried loading an old save game it crashed the engine.
When I entered the Configuration menu, Mods tab, the deleted mods still appeared in Active Mods.
The safer behavior would be to check the config mods.txt list (active mods) against the known available mods (in the mods folder). If there are unknown mods, do not put them in the Active Mods list and spit out warnings to standard error. Something like this:
Mod "frontier" not found, skipping...
We often get bug reports and if the debugging symbols are already in, it is easier for the bug reporters to actually help.
I have a few questions:
The speed of changing equipment plus the support for oversized weapons makes this refactoring well worth it! One of the things I was having trouble with in making new graphics was keeping the hero's animation inside the 128x128 frame including weapons; now that's no longer a factor and I can just focus on making great animations without constraint.
If we run into more questions/concerns, let's talk them out here.
I'll look into seeing if I can do it myself (I like a good challenge), but I think it'd be handy to be able to have events trigger NPC dialogs like so:
[event]
location=x,y,w,h
type=run_once
talker=testnpc
Then you cvan just set up all the requires_* as normal within the npc definition - the only strange thing is the npc wouldn't need a sprite necessarily. That way you can open a dialog box by running across a square or otherwise triggering an event.
This might be used for something like the first dungeon in Polymorphable, where it might be nice to use this, instead of the current msg= and sudden map change.
[event]
location=x,y,w,h
type=teleport
mapmod=object,x,y,tile#
talker=pitwarning
intermap=cavern.txt,x,y
Our bare-bones gettext implementation doesn't currently support multi-line translations. Let's add this feature.
If possible I'd rather not simply use an existing gettext library, as I've heard some of them are incompatible with Windows or hard to port. Anything that makes Flare harder to port is unacceptable.
Besides, there are many features we do not plan to use from a full gettext implementation, and I like our slim version.
I had a report of a player choosing a resolution in the config menu that was larger than their screen size. Then they couldn't start the game or change the screen size back -- the buttons for that were off the bottom of their view.
The player ended up uninstalling and reinstalling to fix this. Not all players are going to know they can edit plaintext config files. This was a frustrating experience for the player, and could have been worse if they had e.g. invested time in a save game and decided to uninstall.
Here are his reported specs: "My video card is a NVIDIA GeForce 9800 GT. My monitor is a wide-flatscreen that goes up to 1366x768"
Sometimes it seems the resolution options are specific to the monitor, but other times it's just whatever the video card can output (I know that's the case with my PC because I'm using an HDTV as a monitor).
Not sure if there's a way to prevent this from happening. Maybe the SDL function to look up resolution options has other ways of being used.
We may be able to mitigate it though. E.g. if we put a "Keep this resolution?" confirmation box at the bottom of the screen, and revert after X seconds. Know of any other games that attempted this? Any smarter way we can deal with this?
We want to move towards random item generation. Let's discuss how this might look; then once we have a clear picture we'll implement.
Base items might look like this:
[item]
id=10
name=Leather Boots
type=feet
level=2
price=5
(all the art and sound info)
Random Item bonuses might look like this:
[item_bonus]
id=20
name=Dwarven
bonus=hp,4,6
price_multiplier=120
level_add=1
quality=high
If we combine these we'll get an item that would look kinda like this in game. The title is green due to the High Quality bonus:
Leather Boots [Dwarven]
Feet
Level 3 (base item plus bonus level add)
Bonus: 5 HP
Price: 6 gold (base item times bonus multiplier)
Note we'll start using that naming convention for random items: "Base Item [Bonus List]". This is mainly to make translating possible (translate the base item and bonus label separately).
That's straightforward. The magic is how we determine what combinations are possible.
Assume we'll allow so many combinations that we can't precalculate them all. So we wouldn't be, for example. making a list of all possible level 8 items. Currently we have the full list of items per level to generate loot.
So we should consider the way we generate loot, and use that to think about how to generate items.
Example way to generate loot:
We want some control over which bonuses match which items. Example, we only want Broken (reduced damage) as a mod on weapons. We'd only want Reinforced (increased absorb) on armor. Speed bonus might only be on boots.
How to do this? Maybe base items will use categories, and each item_bonus has a list of categories of items it's allowed to modify. A dagger might have category=melee,weapon. Leather boots might have category=armor,feet. The Speed bonus would have category=feet.
Item stack will have to be updated to contain a vector of bonuses.
What would the save files and stash look like? We might have to move to one item per line, like this:
carried=base_item,item_quantity
carried=base_item,item_quantity;item_bonus,value;item_bonus,value;item_bonus,value
It might be possible to precompute items combos into unique integers and store those. But maybe it's not worth the obfuscation. Having all the items listed plainly would make it fun and easy to add ridiculous items right into a save file.
The top tier items could have unique names and preset item bonuses. Possibly all Artifacts would be premade in Flare, for instance, along with all Epic quality items. Set items would probably be premade as well.
I suppose we can do this by replacing the bonus lines in items.txt. Instead of specifying a bonus type and value, it could point to a specific item_bonus_id in the item bonuses file.
(submitted by zear)
I opened this issue to discuss steps needed to implement in order for Flare to support handheld platforms.
What I understand as a "handheld platform" is a device, which:
Note that some handheld platforms will have a touchscreen, however I would like to focus here on a situation where keyboard/joystick is the only way of input.
Case study:
GCW Zero - 8 buttons (keyboard interface), d-pad (keyboard interface), analog (joystick interface)
GPH Caanoo - 9 buttons (joystick interface), analog (joystick interface)
Video of the current status of Flare performance on these devices: http://www.youtube.com/watch?v=ymc--9fIAxc
(I encourage to watch it to understand the points I'm raising further on)
== Menu navigation ==
Options menus:
In-game menus:
== Picking up items ==
== NPC Dialog menus ==
== Using the bottom bar ==
== Loading times ==
Loading times should be optimized to reduce their time.
I believe some of the proposed features should also be merged back with the flare-engine when implemented.
Player $subj while he likely shouldn't. This can be reproduced on Avenguard Complex map by teleporting into closed part of room at the top, and using the switch through the wall to open it from inside.
Migrated from clintbellanger/flare#132
Currently when any player or enemy takes non-lethal damage they go through the Hit animation. This causes the creature to stop moving for a moment.
Especially for some enemies, and maybe as an Artifact power, allow Entities to skip this hit animation. They should still take damage. Maybe still play the Hit sound effect?
This will help make some seemingly-tougher creatures that are harder to deal with, especially if they also have high running speeds.
I would be very grateful if someone would write up a Translation tutorial to be posted here:
https://github.com/clintbellanger/flare-engine/wiki/Translations
In this tutorial we can talk about just translating the engine. We'll have a very similar tutorial later for translating the game data of flare-game.
Here's what I imagine the tutorial can look like:
Issue 1: Performance drops on MenuCharacter for me to 8-15 FPS when opened.
Issue 2: MenuCharacter is transparent to mouse click everywhere except scrollbox (scrollbar area without knob also affected).
Should the the NPC rely on the Animation classes?
Or should the class still care for their own sprite?
Pro refactor:
Contra refactor:
Do you have other reasons pro or contra?
I'd go for the refactoring and changing all the required things in flare-game, but we should discuss the way how NPC handle directions in case we decide to refactor.
I don't know how hard it would be to be able to set custom power "class"es from game to game. I'm thinking of something like the following:
[power]
name=Voodoo Blast
class=voodoo
requires_mental_weapon=true
range=512
trait_elemental=fire
[item]
name=Advanced Phlebotinum
type=artifact
bonus=voodoo,stun
Or so that all Ranger powers can be classed as Ranger and have a passive that increases all Ranger ability damage
[power]
name=Keen Eye
requires_class=ranger
damage_multiplier=125
Maybe this would be really, really hard or out-of-scope.
So I originally forked Polymorphable as a fork of flare-engine, so that it'd show up in the network graph. That was overrated. It is probably a very good thing that flare-game ISN'T a fork of flare-engine.
This had the side-effect that I couldn't make my own flare-engine fork (because then I'd have two forks of the same repo, even if one had been renamed), nor could anyone with a pre-existing flare-engine fork fork polymorphable (as Dorkster tried to do). So I've recreated the repo, and it looks exactly the same as when it was a direct fork, except that now I have to merge changes via the terminal instead of via the website. This is the same process we used when it was pennomi/polymorphable, and the same process Clint is probably using for flare-game.
So, good practice when someone wants to do a full conversion mod:
Create a new repo on github, username/new-game-name
$git clone https://github.com/clintbellanger/flare-engine.git
$cd flare-engine
$git remote rm origin
$git remote add origin https://github.com/username/new-game-name.git
$git push origin master
$git remote add upstream https://github.com/clintbellanger/flare-engine.git
Again, downside? Probably harder to track the total number of total conversion mods out there, as they won't show up in the flare-engine network graph. Upside? People can fork the new game as well as flare-engine.
Would it be cool maybe, once we need to count past two, to have a list on flarerpg.org or somewhere of "Games that use the FLARE engine"?
This could cause a crash, as we'd be accessing object[0][0] on an uninitialized pointer.
Migrated from clintbellanger/flare#916
Many games that have an active block button give some kind of bonus for blocking just-in-time. In Bastion the attacker takes damage (even reflecting ranged attacks back!). In Dark Souls there's a parry/riposte system (there parry is a different button than block, but it's a similar feature in effect).
Perhaps when a block begins, we start a block-frame counter. When we resolve an attack, if the block has been active less than X frames, trigger effect Y.
I like this feature because it adds depth to combat without needing a new button nor a new animation.
We'll keep this in mind when working on the Power system for v0.18.
Is this happening for anyone else?
I enable minicore but keep using a high resolution (e.g. 800x600). The tiles don't cover the entire viewport.
It's not an issue if I drop down to 320x240.
There may be a bug in some setting or some logic causing this.
Migrated from clintbellanger/flare#43
Allow the creation of missile powers that reflect when hitting a wall, instead of dissipating. Look for a good spot (maybe the MapCollision class?) to calculate reflection angle.
For fun, try adding a Block-based power that reflects enemy missiles back at the enemy. This could be a very fun power for melee builds vs. pesky ranged creatures.
Vulnerable_element works as an expression of resistance, eg, vulnerable_fire=0 properly reduces fire damage to 0. vulnerable_fire=400 will not multiple fire damage by 4, though. This appears to be related to engine/combat.txt - if max_resist_percent is raised to 400, then vulnerable_fire=400 will work properly.
If the player is dragging an item that came from the carried inventory, and if the item can be equipped, highlight the matching slot for this equipment.
Now that we have more equipment slots, this will help characters put on items without needing to memorize which slots go where.
The simple "attention_glow.png" in fantasycore/images/menus can be used for this purpose. (probably make the image configurable in menus/inventory.txt)
Migrated from clintbellanger/flare#261
Various uses for passive powers should be added.
Some simple passive powers could buff other stats. E.g. +25% to melee weapon damage. These should be factored in when calculating stats.
Other powers can be tied to various passive situations: on_block, on_death, on_hit, etc.
This will allow us to properly code Vengeance (among other things). One part is a passive on_block power that grants a stacking buff. The second part is a melee swing that consumes these stacking buffs to add bonuses.
Perhaps a side effect of the recent fix to moving dead patrolling creatures.
Try killing the patrolling skeleton in the Brothers' Lair Atrium. His square remains blocked.
If an enemy doesn't move, it also doesn't block the hero's movement.
This is part of my quest (along with the already-implemented suppress_hp feature) to try and get some destructible environmental objects into the game, though this should probably be fixed anyways.
To reduce loading times on map change I propose to remember as many objects as possible
from the previous map:
As of now everything gets reloaded from scratch, so the loading times are very long specially on low end hardware.
Seems like it'd be pretty common situation for people updating to 017: alpha_demo mod is disabled by default, and either loading a save or starting a new game will lead to segfault.
Also, we likely need something like a warning message box which suggests a player to enable some mods when a game starts for such cases.
(gdb) run
Starting program: /usr/home/amdmi3/projects/freebsd/ports/games/flare/prefix/bin/flare
[New LWP 110907]
[New Thread 805007400 (LWP 110907/flare)]
[New Thread 80500a000 (LWP 119829/flare)]
2 joysticks were found:
Joy 0) 0x0004 (0)
Joy 1) /dev/uhid1
Using joystick #0.
Unable to open maps/spawn.txt
Unable to find maps/frontier_outpost.txt, loading spawn.txt
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 805007400 (LWP 110907/flare)]
0x00000000004676c1 in MapCollision::unblock (this=0x808fc3264, x=401574741, y=-1094790632) at /usr/home/amdmi3/projects/freebsd/ports/games/flare/work/flare_linux_v017/src/MapCollision.cpp:405
405 if (colmap[tile_x][tile_y] == BLOCKS_ENTITIES) {
(gdb) bt
#0 0x00000000004676c1 in MapCollision::unblock (this=0x808fc3264, x=401574741, y=-1094790632) at /usr/home/amdmi3/projects/freebsd/ports/games/flare/work/flare_linux_v017/src/MapCollision.cpp:405
#1 0x0000000000412d28 in Avatar::logic (this=0x8053bfa00, actionbar_power=0, restrictPowerUse=false) at /usr/home/amdmi3/projects/freebsd/ports/games/flare/work/flare_linux_v017/src/Avatar.cpp:412
#2 0x0000000000445c0f in GameStatePlay::logic (this=0x80503af80) at /usr/home/amdmi3/projects/freebsd/ports/games/flare/work/flare_linux_v017/src/GameStatePlay.cpp:559
#3 0x000000000044b9a3 in GameSwitcher::logic (this=0x805265440) at /usr/home/amdmi3/projects/freebsd/ports/games/flare/work/flare_linux_v017/src/GameSwitcher.cpp:84
#4 0x00000000004d46a4 in mainLoop (args=@0x7fffffffd7e0) at /usr/home/amdmi3/projects/freebsd/ports/games/flare/work/flare_linux_v017/src/main.cpp:145
#5 0x00000000004d4c84 in main (argc=1, argv=0x7fffffffd870) at /usr/home/amdmi3/projects/freebsd/ports/games/flare/work/flare_linux_v017/src/main.cpp:189
(gdb) bt full
#0 0x00000000004676c1 in MapCollision::unblock (this=0x808fc3264, x=401574741, y=-1094790632) at /usr/home/amdmi3/projects/freebsd/ports/games/flare/work/flare_linux_v017/src/MapCollision.cpp:405
tile_x = 6274605
tile_y = -17106104
#1 0x0000000000412d28 in Avatar::logic (this=0x8053bfa00, actionbar_power=0, restrictPowerUse=false) at /usr/home/amdmi3/projects/freebsd/ports/games/flare/work/flare_linux_v017/src/Avatar.cpp:412
stepfx = 748
allowed_to_move = 2
allowed_to_use_power = 5
#2 0x0000000000445c0f in GameStatePlay::logic (this=0x80503af80) at /usr/home/amdmi3/projects/freebsd/ports/games/flare/work/flare_linux_v017/src/GameStatePlay.cpp:559
No locals.
#3 0x000000000044b9a3 in GameSwitcher::logic (this=0x805265440) at /usr/home/amdmi3/projects/freebsd/ports/games/flare/work/flare_linux_v017/src/GameSwitcher.cpp:84
newState = (GameState *) 0x80503af80
#4 0x00000000004d46a4 in mainLoop (args=@0x7fffffffd7e0) at /usr/home/amdmi3/projects/freebsd/ports/games/flare/work/flare_linux_v017/src/main.cpp:145
done = false
max_fps = 30
delay = 33
prevTicks = 3429
nowTicks = 3429
debug_event = false
#5 0x00000000004d4c84 in main (argc=1, argv=0x7fffffffd870) at /usr/home/amdmi3/projects/freebsd/ports/games/flare/work/flare_linux_v017/src/main.cpp:189
args = {
<std::_Vector_base<std::basic_string<char, std::char_traits<char>, std::allocator<char> >,std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >> = {
_M_impl = {
<std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >> = {
<__gnu_cxx::new_allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >> = {<No data fields>}, <No data fields>},
members of std::_Vector_base<std::basic_string<char, std::char_traits<char>, std::allocator<char> >,std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_Vector_impl:
_M_start = 0x0,
_M_finish = 0x0,
_M_end_of_storage = 0x0
}
}, <No data fields>}
Reported by nougoo on the forums. The related crash has been fixed, but the buttons themselves still can't be used.
Let's check to make sure all the added engine strings are translated.
Once everything checks out, let's generate engine.pot file.
Pennomi just told me what this does! It's not intuitive at all from the name. Maybe it should be renamed?
I found a bug hidden deep in the engine code, which is why I open the bug here.
Have an animation definition file, which looks like this:
[melee]
frames=3
duration=90
type=play_once
frame=0,0,133,1569,44,48,18,44
frame=0,1,129,1841,42,51,18,48
...
frames=8
duration=90
type=play_once
frame=0,0,151,3161,29,60,19,52
frame=0,1,122,3161,29,63,14,56
...
So one header section is missing, which leads to being frames being redefined for the current section.
Then something nasty is happening (the memory is shaken quite randomly).
http://about.travis-ci.org/docs/user/getting-started/
offers a a continous integration testing system for free for free projects.
That is pullrequests will be compile checked viewed in the pullrequest page.
I have found script for importing issues from one repo into another
https://github.com/mkorenkov/tools/blob/master/gh-issues-import/gh-issues-import.py
It will import all issues, so some of with will require to be moved manually to flare-game repo. Also maybe we should edit script a little to move only open issues. Or should we import all of them?
Also I have found flare-engine repo on google code(!) during search. Well, I didn't want, but I see old repo has some issues, that are not solved yet. See http://code.google.com/p/flare-engine/issues/list
@zear passed this video to me via irc:
http://www.youtube.com/watch?v=-8Wit7HYVrA&feature=youtu.be
As you can see in the video, when entering areas with lots of enemies the framerate drops, making gameplay annoying.
All enemies there are dead, so it should be not the pathfinding, but the graphics rendering which is still lacking speed.
As of now all entities produce one or more Renderable objects each frame.
These Renderables are then sorted by the map renderer (n log n) and displayed when iterating over the tiles of objects layer.
So here is a proposal to try out:
Do not generate the Renderables each frame, but rather produce them once and have pointers to them. They will be pointed at from both its originating entity and the map renderer.
The maprenderer would not need to sort all the renderables each frame, but could rather only check for required updates in the presorted list.
The entities would also only need to update the renderables and not need to create them from scratch.
If the renderables are kept in a list by the map renderer another adavantage pops up as well:
all the dead enemies are known (and dead enemies don't move), so the dead enemies can be rendered into the background layer and only updated when necessary.
I'm not seeing expected A* behavior from enemies.
Migrated from clintbellanger/flare#401
Would be nice if we could get a new font system. Rendering one font at one size is not exactly ideal in all circumstances.
Not sure how to reproduce this yet, but it's happened twice during my current playthrough.
The shield art will stop displaying even though I still have an active shield.
If an image can't be found, in most cases the game can continue to run.
There are several places where we SDL_Quit when we can't find an image.
Instead we should set the image to NULL, output a warning to stderr, and not draw the image if it's NULL.
So I just wanted to throw out some power ideas, and get feedback from people on whether or not they're currently possible, to provide ideas for the powers revamp. These aren't necessarily powers for flare-game, but that might come up. The names are just to convey the flavor. Anything that requires a tile size is assumed to be 32x32. Possible new power attributes marked with question marks.
[power]
name=Cluster Bomb
#Log a grenade at a target location, shatters into 5 random pieces to strike enemies within 3 tiles
requires_targeting=true
starting_pos=target
count=5
target_neighbor=96
[power]
name=Dragon Breath
#In DnD4e notation, this'd be a blast 3
starting_pos=source
direction=?? //Would this be a possible value? Is there another way to do this?
radius=3
[power]
name=Thrust //For use with spears, javelins, etc. Think of spears in Final Fantasy Tactics.
#Basic spear attack, will strike adjacent enemy as well as the enemy in the tile directly behind it.
starting_pos=source
range=64
multitarget=true
face=true
requires_offense_weapon=true
[power]
name=Cleave
#I'd rename the current "Cleave" power in flare-game to "Whirlwind" and make Cleave a little more traditional
range=64
arc=180? //possibly also useful for Dragon Breath
[power]
name=Flame Wall
#Creates a wall of flame, maybe emanating either parallel or perpendicular to the hero. This one might be totally out of scope?
starting_pos=target
area=wall?
direction=parallel?
range=256 //length of wall
Reported by user tim333:
"i found out if i buy HP bottle and put it on a MP bottle it will make the game crash"
I'm able to replicate it by dragging a stackable item from the Vendor menu onto a different stackable item in my inventory.
String "Unspent skill points:" is not translatable. That's the only one I found but if I'll find more, I'll report here.
Maybe we should try to save log messages alongside the player's save files. It would be nice to keep track of where you left off.
We'd probably have to change where we translate the log strings. Instead of passing the already translated string to addMsg(), pass the untranslated one. That way, addMsg() can store the untranslated one before it gets translated in the game. When we load the game again, these stored messages can translated before adding to the log menu.
This may or may not be a good idea, but it's something to think about.
So I was in the River Encampment, and I totally lucked out with the following sequence:
A) The enemy and I fired our projectiles at roughly the same time.
B) His projectile hit first and killed me
C) My projectile hit him and kill him
D) Causing me to level up. While dead.
I now have a full health bar, but cannot move around. Pressing enter revives me at the start of the map as normal - no freezing or segfaulting or anything, but strange.
Just what it says. One of the more fun ideas Pennomi and I had for Polymorphable was putting on a pile of leaves to sneak past enemies. Ideally, there might be a sneak status (essentially, only invisible while the player is stationary) and an invisibility status, which allows the player to move without being detected (reset all enemies' threat_range to zero while buff is active?), maybe with a variant cancelled upon dealing damage?
Migrated from clintbellanger/flare#576
Originally opened by @clintbellanger
Few classes should have to handle frame counting and resetting, image loading, etc. explicitly. Instead the Animation class should handle these cases.
Right now it's mainly geared towards different Entity animations. We should decouple that a bit.
Examples where we want to use it:
Also, ideally, the class should support Starting and Ending frames, particularly for looped animations. The animation definition could specify which frames are the startup, then the middle is the loop, then the end frames. That way we could easily do many nice things:
I think it would be neat to have a resist stat for effects. Imagine having a Ring of Clarity that prevents getting stunned, or Boots of Escape the reduce the likelihood of being slowed. These stats would be percentages, so there'd be a dice roll for anything in between 0% and 100% resistance.
Doing this could make Warcry more flexible, and perhaps simplify it by defining which effects are negative ahead of time.
There are two cases where we check to see if the mouse position is on an event hotspot:
To avoid performing this check twice, we merged this code. The problem is, the latter case considers distance-to-target. This is now causing event tooltips to not show until you're in range. Event tooltips should work regardless of range.
Let's refactor this so that both actions can use the same mouse-position-check but use the distance check on the activate-event only.
Just chatted with Clint, who said that on_hit and on_half_dead are not implemented yet, I just wanted to make sure there was an issue for it.
Each equipment slot should have an optional default graphic.
GameStatePlay::checkEquipmentChange()
You see here we have the "head" slot as a special case; by default it matches the portrait chosen during the character creation.
You'll also see the "body" slot has a hardcoded "clothes" option, which loads the clothes.png layer.
We'll want to allow optional defaults for every slot. For Flare specifically I've created new "default_" images that we'll use as the new defaults for the chest, hands, legs, and feet slots (replacing the previous "body" slot).
Note we'll also be introducing an actual "head" equipment slots for helmets. It will still use the character head by default, but can be replaced by a helmet item if worn. So we need to make sure this function allows that option.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.