This commit is contained in:
Glen De Cauwsemaecker 2014-03-03 13:11:59 +01:00
commit d57b6cd168
354 changed files with 8692 additions and 5029 deletions
CONTRIBUTING.mdREADME.md
app
application.coffee
assets
collections
initialize.coffee
lib
locale

View file

@ -4,4 +4,4 @@
It just grants us a non-exclusive license to use your contribution and certifies you have the right to contribute the code you submit. For both our sakes, we need this before we can accept a pull request. Don't worry, it's super easy.
For more info, see [http://codecombat.com/legal](http://codecombat.com/legal).
For more info, see [http://codecombat.com/legal](http://codecombat.com/legal).

View file

@ -19,3 +19,39 @@ Whether you're novice or pro, the CodeCombat team is ready to help you implement
### [License](https://github.com/codecombat/codecombat/blob/master/LICENSE)
[MIT](https://github.com/codecombat/codecombat/blob/master/LICENSE) for the code, and [CC-BY](http://codecombat.com/legal) for the art and music. Please also [sign the CodeCombat contributor license agreement](http://codecombat.com/cla) so we can accept your pull requests. It is easy.
### [Join Us!](http://blog.codecombat.com/why-you-should-open-source-your-startup)
![George Saines](http://codecombat.com/images/pages/about/george_small.png)
![Scott Erickson](http://codecombat.com/images/pages/about/scott_small.png)
![Nick Winter](http://codecombat.com/images/pages/about/nick_small.png)
![Michael Schmatz](http://codecombat.com/images/pages/about/michael_small.png)
![Jeremy Arns](http://codecombat.com/images/pages/about/jeremy_small.png)
![Tom Steinbrecher](http://codecombat.com/images/pages/contribute/archmage/tom_small.png)
![Glen De Cauwsemaecker](http://codecombat.com/images/pages/contribute/archmage/glen_small.png)
![Sébastien Moratinos](http://codecombat.com/images/pages/contribute/archmage/sebastien_small.png)
![deepak1556](http://codecombat.com/images/pages/contribute/archmage/deepak_small.png)
![Ronnie Cheng](http://codecombat.com/images/pages/contribute/archmage/ronald_small.png)
![Chloe Fan](http://codecombat.com/images/pages/contribute/archmage/chloe_small.png)
![Rachel Xiang](http://codecombat.com/images/pages/contribute/archmage/rachel_small.png)
![Dan Ristic](http://codecombat.com/images/pages/contribute/archmage/dan_small.png)
![Brad Dickason](http://codecombat.com/images/pages/contribute/archmage/brad_small.png)
![Rebecca Saines](http://codecombat.com/images/pages/contribute/archmage/becca_small.png)
![Laura Watiker](http://codecombat.com/images/pages/contribute/archmage/laura_small.png)
![Shiying Zheng](http://codecombat.com/images/pages/contribute/archmage/shiying_small.png)
![Mischa Lewis-Norelle](http://codecombat.com/images/pages/contribute/archmage/mischa_small.png)
![Paul Buser](http://codecombat.com/images/pages/contribute/archmage/paul_small.png)
![Benjamin Stern](http://codecombat.com/images/pages/contribute/archmage/ben_small.png)
![Alex Cotsarelis](http://codecombat.com/images/pages/contribute/archmage/alex_small.png)
![Ken Stanley](http://codecombat.com/images/pages/contribute/archmage/ken_small.png)
![Robert Moreton](http://codecombat.com/images/pages/contribute/artisan/rob_small.png)
![Andrew Witcher](http://codecombat.com/images/pages/contribute/artisan/andrew_small.png)
![Axandre Oge](http://codecombat.com/images/pages/contribute/artisan/axandre_small.png)
![Katharine Chan](http://codecombat.com/images/pages/contribute/artisan/katharine_small.png)
![Derek Wong](http://codecombat.com/images/pages/contribute/artisan/derek_small.png)
----------
[![](https://dl.dropboxusercontent.com/u/138899/GitHub%20Wikis/challengepost.png)](http://codecombat.challengepost.com/?utm_source-github&utm_medium-oswidget&utm_campaign-codecombat)
[![](http://1-ps.googleusercontent.com/x/s.google-melange.appspot.com/www.google-melange.com/soc/content/2-1-20140225/images/gsoc/logo/920x156xbanner-gsoc2014.png.pagespeed.ic.gdr4t3Igca.png)](http://www.google-melange.com/gsoc/homepage/google/gsoc2014)

View file

@ -20,7 +20,7 @@ elementAcceptsKeystrokes = (el) ->
# not radio, checkbox, range, or color
return (tag is 'textarea' or (tag is 'input' and type in textInputTypes) or el.contentEditable in ["", "true"]) and not (el.readOnly or el.disabled)
COMMON_FILES = ['/images/modal_background.png', '/images/level/code_palette_background.png']
COMMON_FILES = ['/images/pages/base/modal_background.png', '/images/level/code_palette_background.png']
preload = (arrayOfImages) ->
$(arrayOfImages).each ->
$('<img/>')[0].src = @

Binary file not shown.

After

(image error) Size: 5.2 KiB

Binary file not shown.

After

(image error) Size: 138 KiB

Binary file not shown.

Before

(image error) Size: 8.2 KiB

Binary file not shown.

After

(image error) Size: 10 KiB

Binary file not shown.

Before

(image error) Size: 3.4 KiB

Binary file not shown.

After

(image error) Size: 12 KiB

Binary file not shown.

Before

(image error) Size: 2.7 KiB

Binary file not shown.

After

(image error) Size: 9.2 KiB

Binary file not shown.

Before

(image error) Size: 7.8 KiB

Binary file not shown.

After

(image error) Size: 11 KiB

Binary file not shown.

Before

(image error) Size: 7.2 KiB

Binary file not shown.

After

(image error) Size: 12 KiB

Binary file not shown.

After

(image error) Size: 7.9 KiB

Binary file not shown.

After

(image error) Size: 7.7 KiB

Binary file not shown.

After

(image error) Size: 8.9 KiB

Binary file not shown.

After

(image error) Size: 9.6 KiB

Binary file not shown.

After

(image error) Size: 6.6 KiB

Binary file not shown.

After

(image error) Size: 8.6 KiB

Binary file not shown.

After

(image error) Size: 7.6 KiB

Binary file not shown.

After

(image error) Size: 12 KiB

Binary file not shown.

After

(image error) Size: 10 KiB

Binary file not shown.

After

(image error) Size: 8.3 KiB

Binary file not shown.

After

(image error) Size: 6.6 KiB

Binary file not shown.

After

(image error) Size: 8.4 KiB

Binary file not shown.

After

(image error) Size: 8.6 KiB

Binary file not shown.

After

(image error) Size: 9.2 KiB

Binary file not shown.

After

(image error) Size: 8.1 KiB

Binary file not shown.

After

(image error) Size: 8.7 KiB

Binary file not shown.

After

(image error) Size: 9.4 KiB

Binary file not shown.

After

(image error) Size: 8.6 KiB

Binary file not shown.

After

(image error) Size: 8.9 KiB

Binary file not shown.

After

(image error) Size: 9.7 KiB

Binary file not shown.

After

(image error) Size: 9.2 KiB

Binary file not shown.

After

(image error) Size: 7.1 KiB

Binary file not shown.

After

(image error) Size: 48 KiB

Binary file not shown.

After

(image error) Size: 54 KiB

Binary file not shown.

After

(image error) Size: 99 KiB

View file

@ -0,0 +1,2 @@
self._noTransferable = true;
self.onmessage = function(e) { eval(e.data); };

View file

@ -1,140 +0,0 @@
throw "Attempt to load worker_world into main window instead of web worker." if not self.importScripts or not window?
self.window = self
self.workerID = "Worker"
self.logLimit = 200
self.logsLogged = 0
console =
log: ->
self.logsLogged += 1
if self.logsLogged is self.logLimit
self.postMessage
type: 'console-log'
args: ["Log limit " + self.logLimit + " reached; shutting up."]
id: self.workerID
else if self.logsLogged < self.logLimit
args = [].slice.call arguments
for arg in args
if arg and arg.constructor and (arg.constructor.className is "Thang" or arg.isComponent)
arg = arg.toString()
try
self.postMessage
type: 'console-log'
args: args
id: self.workerID
catch error
self.postMessage
type: 'console-log'
args: ["Could not post log: " + args, error.toString(), error.stack, error.stackTrace]
id: self.workerID
console.error = console.info = console.log
self.console = console
importScripts '/javascripts/world.js'
self.transferableSupported = transferableSupported = ->
try
ab = new ArrayBuffer 1
worker.postMessage ab, [ab]
return ab.byteLength is 0
catch error
return false
return false
World = self.require 'lib/world/world'
GoalManager = self.require 'lib/world/GoalManager'
self.runWorld = runWorld = (args) ->
self.postedErrors = {}
self.t0 = new Date()
self.firstWorld = args.firstWorld
self.postedErrors = false
self.logsLogged = 0
try
self.world = new World args.worldName, args.userCodeMap
if args.level
self.world.loadFromLevel args.level, true
self.goalManager = new GoalManager self.world
self.goalManager.setGoals args.goals
self.goalManager.setCode args.userCodeMap
self.goalManager.worldGenerationWillBegin()
self.world.setGoalManager self.goalManager
catch error
self.onWorldError error
return
Math.random = self.world.rand.randf
self.world.loadFrames self.onWorldLoaded, self.onWorldError, self.onWorldLoadProgress
self.onWorldLoaded = onWorldLoaded = () ->
self.goalManager.worldGenerationEnded()
t1 = new Date()
diff = t1 - self.t0
transferableSupported = self.transferableSupported()
try
serialized = self.world.serialize()
catch error
console.log "World serialization error:", error.toString() + "\n" + error.stack or error.stackTrace
t2 = new Date()
try
if transferableSupported
self.postMessage(
type: 'new-world'
serialized: serialized.serializedWorld
goalStates: self.goalManager.getGoalStates()
, serialized.transferableObjects)
else
self.postMessage
type: 'new-world'
serialized: serialized.serializedWorld
goalStates: self.goalManager.getGoalStates()
catch error
console.log "World delivery error:", error.toString + "\n" + error.stack or error.stackTrace
t3 = new Date()
console.log "And it was so: (" + (diff / self.world.totalFrames).toFixed(3) + "ms per frame,", self.world.totalFrames, "frames)\nSimulation :"
self.world = null
self.onWorldError = onWorldError = (error) ->
if error instanceof Aether.problems.UserCodeProblem
unless self.postedErrors[error.key]
problem = error.serialize()
self.postMessage
type: 'user-code-problem'
problem: problem
self.postedErrors[error.key] = problem
else
console.log "Non-UserCodeError:", error.toString() + "\n" + error.stack or error.stackTrace
return true
self.onWorldLoadProgress = onWorldLoadProgress = (progress) ->
self.postMessage
type: 'world-load-progress-changed'
progress: progress
self.abort = abort = ->
if self.world and self.world.name
console.log "About to abort:", self.world.name, typeof self.world.abort
self.world?.abort()
self.world = null
self.postMessage
type: 'abort'
self.reportIn = reportIn = ->
self.postMessage
type: 'reportIn'
self.addEventListener 'message', (event) ->
self[event.data.func](event.data.args)

View file

@ -35,13 +35,6 @@ console.error = console.info = console.log;
self.console = console;
importScripts('/javascripts/world.js');
// Since this is run synchronously on the main thread, we might consider splitting it up and sending "ready":
//xhr.onload = function() {
// eval(this.responseText);
// postMessage("ready");
//};
//xhr.open("get", "script.js");
//xhr.send();
// We could do way more from this: http://stackoverflow.com/questions/10653809/making-webworkers-a-safe-environment
Object.defineProperty(self, "XMLHttpRequest", {
@ -158,3 +151,4 @@ self.addEventListener('message', function(event) {
self[event.data.func](event.data.args);
});
self.postMessage({type: 'worker-initialized'});

View file

@ -0,0 +1,11 @@
CocoCollection = require 'models/CocoCollection'
LevelSession = require 'models/LevelSession'
module.exports = class LeaderboardCollection extends CocoCollection
url: ''
model: LevelSession
constructor: (level, options) ->
super()
options ?= {}
@url = "/db/level/#{level.get('original')}.#{level.get('version').major}/leaderboard?#{$.param(options)}"

View file

@ -1,14 +1,24 @@
app = require 'application'
auth = require 'lib/auth'
$ ->
init = ->
app.initialize()
Backbone.history.start({ pushState: true })
handleNormalUrls()
treemaExt = require 'treema-ext'
treemaExt.setup()
filepicker.setKey('AvlkNoldcTOU4PvKi2Xm7z')
$ ->
# Make sure we're "logged in" first.
if auth.me.id
init()
else
Backbone.Mediator.subscribeOnce 'me:synced', init
window.init = init
handleNormalUrls = ->
# http://artsy.github.com/blog/2012/06/25/replacing-hashbang-routes-with-pushstate/
$(document).on "click", "a[href^='/']", (event) ->

View file

@ -33,7 +33,7 @@ class Media
class AudioPlayer extends CocoClass
subscriptions:
'play-sound': (e) -> @playInterfaceSound e.trigger
'play-sound': (e) -> @playInterfaceSound e.trigger, e.volume
constructor: () ->
super()
@ -70,17 +70,17 @@ class AudioPlayer extends CocoClass
filename = "/file/interface/#{name}#{@ext}"
@preloadSound filename, name
playInterfaceSound: (name) ->
playInterfaceSound: (name, volume=1) ->
filename = "/file/interface/#{name}#{@ext}"
if filename of cache and createjs.Sound.loadComplete filename
@playSound name
createjs.Sound.play name
@playSound name, volume
else
@preloadInterfaceSounds [name] unless filename of cache
@soundsToPlayWhenLoaded[name] = true
playSound: (name) ->
createjs.Sound.play name, {volume: me.get('volume')}
@soundsToPlayWhenLoaded[name] = volume
playSound: (name, volume=1, delay=0) ->
instance = createjs.Sound.play name, {volume: (me.get('volume') ? 1) * volume, delay: delay}
instance
# # TODO: load Interface sounds somehow, somewhere, somewhen
@ -108,8 +108,8 @@ class AudioPlayer extends CocoClass
return if not media
media.loaded = true
media.progress = 1.0
if @soundsToPlayWhenLoaded[media.name]
@playSound media.name
if volume = @soundsToPlayWhenLoaded[media.name]
@playSound media.name, volume
@soundsToPlayWhenLoaded[media.name] = false
@notifyProgressChanged()
@ -124,9 +124,3 @@ class AudioPlayer extends CocoClass
module.exports = new AudioPlayer()
average = (numbers) ->
return 0 if numbers.length is 0
sum = 0
sum += num for num in numbers
return sum / numbers.length

View file

@ -6,7 +6,7 @@ makeScopeName = -> "class-scope-#{classCount++}"
module.exports = class CocoClass
subscriptions: {}
shortcuts: {}
# setup/teardown
constructor: ->
@ -19,13 +19,15 @@ module.exports = class CocoClass
destroy: ->
# teardown subscriptions, prevent new ones
@destroyed = true
@stopListening?()
@unsubscribeAll()
@stopListeningToShortcuts()
@[key] = undefined for key of @
@destroyed = true
@destroy = ->
# subscriptions
listenToSubscriptions: ->
# for initting subscriptions
return unless Backbone?.Mediator?
@ -46,7 +48,7 @@ module.exports = class CocoClass
for channel, func of @subscriptions
func = utils.normalizeFunc(func, @)
Backbone.Mediator.unsubscribe(channel, func, @)
# keymaster shortcuts
listenToShortcuts: ->
@ -54,7 +56,7 @@ module.exports = class CocoClass
for shortcut, func of @shortcuts
func = utils.normalizeFunc(func, @)
key(shortcut, @scope, _.bind(func, @))
stopListeningToShortcuts: ->
return unless key?
key.deleteScope(@scope)
key.deleteScope(@scope)

View file

@ -76,6 +76,3 @@ module.exports = GPlusHandler = class GPlusHandler extends CocoClass
storage.save(CURRENT_USER_KEY, model.attributes)
window.location.reload()
})
destroy: ->
super()

View file

@ -1,9 +1,10 @@
{now} = require './world/world_utils'
{now} = require 'lib/world/world_utils'
World = require 'lib/world/world'
## Uncomment to imitate IE9 (and in world_utils.coffee)
#window.Worker = null
#window.Float32Array = null
# (except that we won't have included vendor_with_box2d.js, so Collision won't run, things won't move, etc.)
# Also uncomment vendor_with_box2d.js in index.html if you want Collision to run and things to move.
module.exports = class God
@ids: ['Athena', 'Baldr', 'Crom', 'Dagr', 'Eris', 'Freyja', 'Great Gish', 'Hades', 'Ishtar', 'Janus', 'Khronos', 'Loki', 'Marduk', 'Negafook', 'Odin', 'Poseidon', 'Quetzalcoatl', 'Ra', 'Shiva', 'Thor', 'Umvelinqangi', 'Týr', 'Vishnu', 'Wepwawet', 'Xipe Totec', 'Yahweh', 'Zeus', '上帝', 'Tiamat', '盘古', 'Phoebe', 'Artemis', 'Osiris', "嫦娥", 'Anhur', 'Teshub', 'Enlil', 'Perkele', 'Aether', 'Chaos', 'Hera', 'Iris', 'Theia', 'Uranus', 'Stribog', 'Sabazios', 'Izanagi', 'Ao', 'Tāwhirimātea', 'Tengri', 'Inmar', 'Torngarsuk', 'Centzonhuitznahua', 'Hunab Ku', 'Apollo', 'Helios', 'Thoth', 'Hyperion', 'Alectrona', 'Eos', 'Mitra', 'Saranyu', 'Freyr', 'Koyash', 'Atropos', 'Clotho', 'Lachesis', 'Tyche', 'Skuld', 'Urðr', 'Verðandi', 'Camaxtli', 'Huhetotl', 'Set', 'Anu', 'Allah', 'Anshar', 'Hermes', 'Lugh', 'Brigit', 'Manannan Mac Lir', 'Persephone', 'Mercury', 'Venus', 'Mars', 'Azrael', 'He-Man', 'Anansi', 'Issek', 'Mog', 'Kos', 'Amaterasu Omikami', 'Raijin', 'Susanowo', 'Blind Io', 'The Lady', 'Offler', 'Ptah', 'Anubis', 'Ereshkigal', 'Nergal', 'Thanatos', 'Macaria', 'Angelos', 'Erebus', 'Hecate', 'Hel', 'Orcus', 'Ishtar-Deela Nakh', 'Prometheus', 'Hephaestos', 'Sekhmet', 'Ares', 'Enyo', 'Otrera', 'Pele', 'Hadúr', 'Hachiman', 'Dayisun Tngri', 'Ullr', 'Lua', 'Minerva']
@ -11,31 +12,63 @@ module.exports = class God
@lastID = (if @lastID? then @lastID + 1 else Math.floor(@ids.length * Math.random())) % @ids.length
@ids[@lastID]
maxAngels: 2 # how many concurrent web workers to use; if set past 8, make up more names
worldWaiting: false # whether we're waiting for a worker to free up and run the world
constructor: (@world, @level) ->
constructor: (options) ->
@id = God.nextID()
options ?= {}
@maxAngels = options.maxAngels ? 2 # How many concurrent web workers to use; if set past 8, make up more names
@maxWorkerPoolSize = options.maxWorkerPoolSize ? 2 # ~20MB per idle worker
@angels = []
@firstWorld = true
Backbone.Mediator.subscribe 'tome:cast-spells', @onTomeCast, @
@fillWorkerPool = _.throttle @fillWorkerPool, 3000, leading: false
@fillWorkerPool()
onTomeCast: (e) ->
return if @dead
@spells = e.spells
@createWorld()
fillWorkerPool: =>
return unless Worker
@workerPool ?= []
if @workerPool.length < @maxWorkerPoolSize
@workerPool.push @createWorker()
if @workerPool.length < @maxWorkerPoolSize
@fillWorkerPool()
getWorker: ->
@fillWorkerPool()
worker = @workerPool?.shift()
return worker if worker
@createWorker()
createWorker: ->
worker = new Worker '/javascripts/workers/worker_world.js'
worker.creationTime = new Date()
worker.addEventListener 'message', @onWorkerMessage
worker
onWorkerMessage: (event) =>
worker = event.target
if event.data.type is 'worker-initialized'
#console.log "Worker initialized after", ((new Date()) - worker.creationTime), "ms (before it was needed)"
worker.initialized = true
worker.removeEventListener 'message', @onWorkerMessage
getAngel: ->
freeAngel = null
for angel in @angels
return angel.enslave() unless angel.busy
if angel.busy
angel.abort()
else
freeAngel ?= angel
return freeAngel.enslave() if freeAngel
maxedOut = @angels.length is @maxAngels
if not maxedOut
angel = new Angel @
@angels.push angel
return angel.enslave()
oldestAngel = {started: new Date(2099, 1, 1)}
for angel in @angels
oldestAngel = angel if angel.started < oldestAngel.started
oldestAngel.abort()
null
angelInfinitelyLooped: (angel) ->
@ -65,8 +98,9 @@ module.exports = class God
else
@worldWaiting = true
return
#console.log "going to run world with code", @getUserCodeMap()
angel.worker.postMessage {func: 'runWorld', args: {
worldName: @world.name
worldName: @level.name
userCodeMap: @getUserCodeMap()
level: @level
firstWorld: @firstWorld
@ -80,7 +114,7 @@ module.exports = class God
@latestWorldCreation = worldCreation
@latestGoalStates = goalStates
window.BOX2D_ENABLED = false # Flip this off so that if we have box2d in the namespace, the Collides Components still don't try to create bodies for deserialized Thangs upon attachment
@world.constructor.deserialize serialized, @world.classMap, @lastSerializedWorldFrames, worldCreation, @finishBeholdingWorld
World.deserialize serialized, @worldClassMap, @lastSerializedWorldFrames, worldCreation, @finishBeholdingWorld
window.BOX2D_ENABLED = true
@lastSerializedWorldFrames = serialized.frames
@ -88,11 +122,14 @@ module.exports = class God
newWorld.findFirstChangedFrame @world
@world = newWorld
errorCount = (t for t in @world.thangs when t.errorsOut).length
Backbone.Mediator.publish('god:new-world-created', world: @world, firstWorld: @firstWorld, errorCount: errorCount, goalStates: @latestGoalStates)
Backbone.Mediator.publish('god:new-world-created', world: @world, firstWorld: @firstWorld, errorCount: errorCount, goalStates: @latestGoalStates, team: me.team)
for scriptNote in @world.scriptNotes
Backbone.Mediator.publish scriptNote.channel, scriptNote.event
@goalManager?.world = newWorld
@firstWorld = false
@testWorld = null
unless _.find @angels, 'busy'
@spells = null # Don't hold onto old spells; memory leaks
getUserCodeMap: ->
userCodeMap = {}
@ -102,10 +139,15 @@ module.exports = class God
userCodeMap
destroy: ->
worker.removeEventListener 'message', @onWorkerMessage for worker in @workerPool ? []
angel.destroy() for angel in @angels
@dead = true
Backbone.Mediator.unsubscribe('tome:cast-spells', @onTomeCast, @)
@goalManager?.destroy()
@goalManager = null
@fillWorkerPool = null
@simulateWorld = null
@onWorkerMessage = null
#### Bad code for running worlds on main thread (profiling / IE9) ####
simulateWorld: =>
@ -129,7 +171,7 @@ module.exports = class God
@latestGoalStates = @testGM?.getGoalStates()
serialized = @testWorld.serialize().serializedWorld
window.BOX2D_ENABLED = false
@testWorld.constructor.deserialize serialized, @world.classMap, @lastSerializedWorldFrames, @t0, @finishBeholdingWorld
World.deserialize serialized, @worldClassMap, @lastSerializedWorldFrames, @t0, @finishBeholdingWorld
window.BOX2D_ENABLED = true
@lastSerializedWorldFrames = serialized.frames
@ -152,8 +194,8 @@ class Angel
@ids[@lastID]
# https://github.com/codecombat/codecombat/issues/81 -- TODO: we need to wait for worker initialization first
infiniteLoopIntervalDuration: 1500000 # check this often (must be more than the others added)
infiniteLoopTimeoutDuration: 1500 # wait this long when we check
infiniteLoopIntervalDuration: 7500 # check this often (must be more than the others added)
infiniteLoopTimeoutDuration: 2500 # wait this long when we check
abortTimeoutDuration: 500 # give in-process or dying workers this long to give up
constructor: (@god) ->
@id = Angel.nextID()
@ -164,13 +206,14 @@ class Angel
@spawnWorker()
spawnWorker: ->
@worker = new Worker '/javascripts/workers/worker_world.js'
@worker = @god.getWorker()
@listen()
enslave: ->
@busy = true
@started = new Date()
@purgatoryTimer = setInterval @testWorker, @infiniteLoopIntervalDuration
@spawnWorker() unless @worker
@
free: ->
@ -178,24 +221,42 @@ class Angel
@started = null
clearInterval @purgatoryTimer
@purgatoryTimer = null
if @worker
worker = @worker
onWorkerMessage = @onWorkerMessage
_.delay ->
worker.terminate()
worker.removeEventListener 'message', onWorkerMessage
, 2000
@worker = null
@
abort: ->
return unless @worker
@abortTimeout = _.delay @terminate, @abortTimeoutDuration
@worker.postMessage {func: 'abort'}
terminate: =>
@worker.terminate()
@worker?.terminate()
@worker?.removeEventListener 'message', @onWorkerMessage
@worker = null
return if @dead
@spawnWorker()
@free()
@god.angelAborted @
destroy: ->
@dead = true
@finishBeholdingWorld = null
@abort()
@terminate = null
@testWorker = null
@condemnWorker = null
@onWorkerMessage = null
testWorker: =>
unless @worker.initialized
console.warn "Worker", @id, "hadn't even loaded the scripts yet after", @infiniteLoopIntervalDuration, "ms."
return
@worker.postMessage {func: 'reportIn'}
@condemnTimeout = _.delay @condemnWorker, @infiniteLoopTimeoutDuration
@ -204,23 +265,26 @@ class Angel
@abort()
listen: ->
@worker.addEventListener 'message', (event) =>
switch event.data.type
when 'new-world'
@god.beholdWorld @, event.data.serialized, event.data.goalStates
when 'world-load-progress-changed'
Backbone.Mediator.publish 'god:world-load-progress-changed', event.data unless @dead
when 'console-log'
console.log "|" + @god.id + "'s " + @id + "|", event.data.args...
when 'user-code-problem'
@god.angelUserCodeProblem @, event.data.problem
when 'abort'
#console.log @id, "aborted."
clearTimeout @abortTimeout
@free()
@god.angelAborted @
@worker.terminate() if @god.dead
when 'reportIn'
clearTimeout @condemnTimeout
else
console.log "Unsupported message:", event.data
@worker.addEventListener 'message', @onWorkerMessage
onWorkerMessage: (event) =>
switch event.data.type
when 'worker-initialized'
console.log "Worker", @id, "initialized after", ((new Date()) - @worker.creationTime), "ms (we had been waiting for it)"
when 'new-world'
@god.beholdWorld @, event.data.serialized, event.data.goalStates
when 'world-load-progress-changed'
Backbone.Mediator.publish 'god:world-load-progress-changed', event.data unless @dead
when 'console-log'
console.log "|" + @god.id + "'s " + @id + "|", event.data.args...
when 'user-code-problem'
@god.angelUserCodeProblem @, event.data.problem
when 'abort'
#console.log @id, "aborted."
clearTimeout @abortTimeout
@free()
@god.angelAborted @
when 'reportIn'
clearTimeout @condemnTimeout
else
console.log "Unsupported message:", event.data

View file

@ -21,18 +21,19 @@ module.exports = class LevelBus extends Bus
'thang-code-ran': 'onCodeRan'
'level-show-victory': 'onVictory'
'tome:spell-changed': 'onSpellChanged'
'tome:spell-created': 'onSpellCreated'
constructor: ->
super(arguments...)
@changedSessionProperties = {}
@saveSession = _.debounce(@saveSession, 1000, {maxWait: 5000})
init: ->
super()
@fireScriptsRef = @fireRef?.child('scripts')
setSession: (@session) ->
@session.on('change:multiplayer', @onMultiplayerChanged)
@session.on 'change:multiplayer', @onMultiplayerChanged, @
onPoint: ->
return true unless @session?.get('multiplayer')
@ -54,14 +55,14 @@ module.exports = class LevelBus extends Bus
@wizardRef?.child('targetPos').set(wizardSprite?.targetPos or null)
@wizardRef?.child('targetSprite').set(wizardSprite?.targetSprite?.thang.id or null)
@wizardRef?.child('wizardColor1').set(me.get('wizardColor1') or 0.0)
disconnect: ->
@wizardRef?.off()
@wizardRef = null
@fireScriptsRef?.off()
@fireScriptsRef = null
super()
removeFirebaseData: (callback) ->
return callback?() unless @myConnection
@myConnection.child('connected')
@ -77,26 +78,44 @@ module.exports = class LevelBus extends Bus
onEditingBegan: -> @wizardRef?.child('editing').set(true)
onEditingEnded: -> @wizardRef?.child('editing').set(false)
# HACK: Backbone does not work with nested documents, but we want to
# patch only those props that have changed. Look into plugins to
# give Backbone support for nested docs and update the code here.
# TODO: The LevelBus doesn't need to be in charge of updating the
# LevelSession object. Either break this off into a separate class
# or have the LevelSession object listen for all these events itself.
setSpells: (spells) ->
@onSpellCreated spell: spell for spellKey, spell of spells
onSpellChanged: (e) ->
return unless @onPoint()
code = @session.get('code')
code ?= {}
parts = e.spell.spellKey.split('/')
code[parts[0]] ?= {}
code[parts[0]][parts[1]] = e.spell.getSource()
@changedSessionProperties.code = true
@session.set({'code': code})
@saveSession()
onSpellCreated: (e) ->
return unless @onPoint()
spellTeam = e.spell.team
@teamSpellMap ?= {}
@teamSpellMap[spellTeam] ?= []
unless e.spell.spellKey in @teamSpellMap[spellTeam]
@teamSpellMap[spellTeam].push e.spell.spellKey
@changedSessionProperties.teamSpells = true
@session.set({'teamSpells': @teamSpellMap})
@saveSession()
if spellTeam is me.team
@onSpellChanged e # Save the new spell to the session, too.
onScriptStateChanged: (e) ->
return unless @onPoint()
@fireScriptsRef?.update(e)
@ -198,7 +217,7 @@ module.exports = class LevelBus extends Bus
@changedSessionProperties.chat = true
@saveSession()
onMultiplayerChanged: =>
onMultiplayerChanged: ->
@changedSessionProperties.multiplayer = true
@session.updatePermissions()
@changedSessionProperties.permissions = true
@ -212,8 +231,12 @@ module.exports = class LevelBus extends Bus
patch = {}
patch[prop] = @session.get(prop) for prop of @changedSessionProperties
@changedSessionProperties = {}
# since updates are coming fast and loose for session objects
# don't let what the server returns overwrite changes since the save began
tempSession = new LevelSession _id:@session.id
tempSession.save(patch, {patch: true})
destroy: ->
@session.off 'change:multiplayer', @onMultiplayerChanged, @
super()

View file

@ -19,148 +19,179 @@ module.exports = class LevelLoader extends CocoClass
spriteSheetsBuilt: 0
spriteSheetsToBuild: 0
subscriptions:
'god:new-world-created': 'loadSoundsForWorld'
constructor: (@levelID, @supermodel, @sessionID) ->
constructor: (options) ->
super()
@supermodel = options.supermodel
@levelID = options.levelID
@sessionID = options.sessionID
@opponentSessionID = options.opponentSessionID
@team = options.team
@headless = options.headless
@loadSession()
@loadLevelModels()
@loadAudio()
@playJingle()
setTimeout (=> @update()), 1 # lets everything else resolve first
_.defer @update # Lets everything else resolve first
playJingle: ->
jingles = ["ident_1", "ident_2"]
AudioPlayer.playInterfaceSound jingles[Math.floor Math.random() * jingles.length]
return if @headless
# Apparently the jingle, when it tries to play immediately during all this loading, you can't hear it.
# Add the timeout to fix this weird behavior.
f = ->
jingles = ["ident_1", "ident_2"]
AudioPlayer.playInterfaceSound jingles[Math.floor Math.random() * jingles.length]
setTimeout f, 500
# Session Loading
loadSession: ->
url = if @sessionID then "/db/level_session/#{@sessionID}" else "/db/level/#{@levelID}/session"
if @sessionID
url = "/db/level_session/#{@sessionID}"
else
url = "/db/level/#{@levelID}/session"
url += "?team=#{@team}" if @team
@session = new LevelSession()
@session.url = -> url
@session.fetch()
@session.once 'sync', @onSessionLoaded
onSessionLoaded: =>
# Unless you specify cache:false, sometimes the browser will use a cached session
# and players will 'lose' code
@session.fetch({cache:false})
@session.once 'sync', @onSessionLoaded, @
if @opponentSessionID
@opponentSession = new LevelSession()
@opponentSession.url = "/db/level_session/#{@opponentSessionID}"
@opponentSession.fetch()
@opponentSession.once 'sync', @onSessionLoaded, @
sessionsLoaded: ->
@session.loaded and ((not @opponentSession) or @opponentSession.loaded)
onSessionLoaded: ->
# TODO: maybe have all non versioned models do this? Or make it work to PUT/PATCH to relative urls
@session.url = -> '/db/level.session/' + @id
@update()
if @session.loaded
@session.url = -> '/db/level.session/' + @id
@update() if @sessionsLoaded()
# Supermodel (Level) Loading
loadLevelModels: ->
@supermodel.once 'loaded-all', @onSupermodelLoadedAll
@supermodel.on 'loaded-one', @onSupermodelLoadedOne
@supermodel.once 'error', @onSupermodelError
@supermodel.on 'loaded-one', @onSupermodelLoadedOne, @
@supermodel.once 'error', @onSupermodelError, @
@level = @supermodel.getModel(Level, @levelID) or new Level _id: @levelID
levelID = @levelID
headless = @headless
@supermodel.shouldPopulate = (model) =>
@supermodel.shouldPopulate = (model) ->
# if left unchecked, the supermodel would load this level
# and every level next on the chain. This limits the population
handles = [model.id, model.get 'slug']
return model.constructor.className isnt "Level" or @levelID in handles
return model.constructor.className isnt "Level" or levelID in handles
@supermodel.shouldLoadProjection = (model) ->
return true if headless and model.constructor.className is 'ThangType'
false
@supermodel.populateModel @level
onSupermodelError: =>
msg = $.i18n.t('play_level.level_load_error',
defaultValue: "Level could not be loaded.")
@$el.html('<div class="alert">' + msg + '</div>')
onSupermodelError: ->
onSupermodelLoadedOne: (e) =>
@notifyProgress()
# if e.model.type() is 'ThangType'
# thangType = e.model
# options = {async: true}
# if thangType.get('name') is 'Wizard'
# options.colorConfig = me.get('wizard')?.colorConfig or {}
# building = thangType.buildSpriteSheet options
# if building
# @spriteSheetsToBuild += 1
# thangType.on 'build-complete', =>
# @spriteSheetsBuilt += 1
# @notifyProgress()
onSupermodelLoadedAll: =>
@trigger 'loaded-supermodel'
@stopListening(@supermodel)
onSupermodelLoadedOne: (e) ->
@buildSpriteSheetsForThangType e.model if not @headless and e.model instanceof ThangType
@update()
# Things to do when either the Session or Supermodel load
update: ->
update: =>
@notifyProgress()
return if @updateCompleted
return unless @supermodel.finished() and @session.loaded
return unless @supermodel?.finished() and @sessionsLoaded()
@denormalizeSession()
@loadLevelSounds()
app.tracker.updatePlayState(@level, @session)
@updateCompleted = true
denormalizeSession: ->
return if @session.get 'levelName'
return if @sessionDenormalized
patch =
'levelName': @level.get('name')
'levelID': @level.get('slug') or @level.id
if me.id is @session.get 'creator'
patch.creatorName = me.get('name')
@session.set key, value for key, value of patch
tempSession = new LevelSession _id: @session.id
tempSession.save(patch, {patch: true})
for key, value of patch
if @session.get(key) is value
delete patch[key]
unless _.isEmpty patch
@session.set key, value for key, value of patch
tempSession = new LevelSession _id: @session.id
tempSession.save(patch, {patch: true})
@sessionDenormalized = true
# World init
# Building sprite sheets
initWorld: ->
return if @world
@world = new World @level.get('name')
serializedLevel = @level.serialize(@supermodel)
@world.loadFromLevel serializedLevel, false
@buildSpriteSheets()
grabThangTypeTeams: ->
@grabTeamConfigs()
@thangTypeTeams = {}
for thang in @level.get('thangs')
for component in thang.components
if team = component.config?.team
@thangTypeTeams[thang.thangType] ?= []
@thangTypeTeams[thang.thangType].push team unless team in @thangTypeTeams[thang.thangType]
break
@thangTypeTeams
buildSpriteSheets: ->
thangTypes = {}
thangTypes[tt.get('name')] = tt for tt in @supermodel.getModels(ThangType)
grabTeamConfigs: ->
for system in @level.get('systems')
if @teamConfigs = system.config?.teamConfigs
break
unless @teamConfigs
# Hack: pulled from Alliance System code. TODO: put in just one place.
@teamConfigs = {"humans":{"superteam":"humans","color":{"hue":0,"saturation":0.75,"lightness":0.5},"playable":true},"ogres":{"superteam":"ogres","color":{"hue":0.66,"saturation":0.75,"lightness":0.5},"playable":false},"neutral":{"superteam":"neutral","color":{"hue":0.33,"saturation":0.75,"lightness":0.5}}}
@teamConfigs
colorConfigs = @world.getTeamColors()
thangsProduced = {}
baseOptions = {resolutionFactor: 4, async: true}
for thang in @world.thangs
continue unless thang.spriteName
thangType = thangTypes[thang.spriteName]
options = thang.getSpriteOptions(colorConfigs)
options.async = true
thangsProduced[thang.spriteName] = true
@buildSpriteSheet(thangType, options)
for thangName, thangType of thangTypes
continue if thangsProduced[thangName]
thangType.spriteOptions = {resolutionFactor: 4, async: true}
@buildSpriteSheet(thangType, thangType.spriteOptions)
buildSpriteSheetsForThangType: (thangType) ->
@grabThangTypeTeams() unless @thangTypeTeams
for team in @thangTypeTeams[thangType.get('original')] ? [null]
spriteOptions = {resolutionFactor: 4, async: true}
if thangType.get('kind') is 'Floor'
spriteOptions.resolutionFactor = 2
if team and color = @teamConfigs[team]?.color
spriteOptions.colorConfig = team: color
@buildSpriteSheet thangType, spriteOptions
buildSpriteSheet: (thangType, options) ->
if thangType.get('name') is 'Wizard'
options.colorConfig = me.get('wizard')?.colorConfig or {}
building = thangType.buildSpriteSheet options
return unless building
console.log 'Building:', thangType.get('name'), options
#console.log 'Building:', thangType.get('name'), options
t0 = new Date()
@spriteSheetsToBuild += 1
thangType.on 'build-complete', =>
thangType.once 'build-complete', =>
@spriteSheetsBuilt += 1
@notifyProgress()
console.log "Built", thangType.get('name'), 'after', ((new Date()) - t0), 'ms'
# World init
initWorld: ->
return if @initialized
@initialized = true
@world = new World @level.get('name')
serializedLevel = @level.serialize(@supermodel)
@world.loadFromLevel serializedLevel, false
# Initial Sound Loading
loadAudio: ->
return if @headless
AudioPlayer.preloadInterfaceSounds ["victory"]
loadLevelSounds: ->
return if @headless
scripts = @level.get 'scripts'
return unless scripts
@ -174,38 +205,32 @@ module.exports = class LevelLoader extends CocoClass
for trigger, sounds of thangType.get('soundTriggers') or {} when trigger isnt 'say'
AudioPlayer.preloadSoundReference sound for sound in sounds
# Dynamic sound loading
loadSoundsForWorld: (e) ->
world = e.world
thangTypes = @supermodel.getModels(ThangType)
for [spriteName, message] in world.thangDialogueSounds()
continue unless thangType = _.find thangTypes, (m) -> m.get('name') is spriteName
continue unless sound = AudioPlayer.soundForDialogue message, thangType.get('soundTriggers')
filename = AudioPlayer.preloadSoundReference sound
# everything else sound wise is loaded as needed as worlds are generated
allDone: ->
@supermodel.finished() and @session.loaded and @spriteSheetsBuilt is @spriteSheetsToBuild
@supermodel.finished() and @sessionsLoaded() and @spriteSheetsBuilt is @spriteSheetsToBuild
progress: ->
return 0 unless @level.loaded
overallProgress = 0
supermodelProgress = @supermodel.progress()
overallProgress += supermodelProgress * 0.7
overallProgress += 0.1 if @session.loaded
spriteMapProgress = if supermodelProgress is 1 then 0.2 else 0
spriteMapProgress *= @spriteSheetsBuilt / @spriteSheetsToBuild if @spriteSheetsToBuild
overallProgress += 0.1 if @sessionsLoaded()
if @headless
spriteMapProgress = 0.2
else
spriteMapProgress = if supermodelProgress is 1 then 0.2 else 0
spriteMapProgress *= @spriteSheetsBuilt / @spriteSheetsToBuild if @spriteSheetsToBuild
overallProgress += spriteMapProgress
return overallProgress
notifyProgress: ->
Backbone.Mediator.publish 'level-loader:progress-changed', progress: @progress()
@initWorld() if @allDone()
# @trigger 'ready-to-init-world' if @allDone()
@trigger 'loaded-all' if @progress() is 1
destroy: ->
@supermodel.off 'loaded-one', @onSupermodelLoadedOne
@world = null # don't hold onto garbage
@update = null
super()

View file

@ -93,7 +93,12 @@ module.exports = class LoadingScreen extends CocoClass
@text.text = "BUILDING" if @progress is 1
@progressBar.scaleX = @progress
@stage.update()
showReady: ->
@text.text = 'READY'
@text.regX = @text.getMeasuredWidth() / 2
@stage.update()
destroy: ->
@stage.canvas = null
super()
super()

View file

@ -2,6 +2,8 @@
gplusClientID = "800329290710-j9sivplv2gpcdgkrsis9rff3o417mlfa.apps.googleusercontent.com"
go = (path) -> -> @routeDirectly path, arguments
module.exports = class CocoRouter extends Backbone.Router
subscribe: ->
Backbone.Mediator.subscribe 'gapi-loaded', @onGPlusAPILoaded, @
@ -15,6 +17,9 @@ module.exports = class CocoRouter extends Backbone.Router
# editor views tend to have the same general structure
'editor/:model(/:slug_or_id)(/:subview)': 'editorModelView'
# Experimenting with direct links
'play/ladder/:levelID/team/:team': go('play/ladder/team_view')
# db and file urls call the server directly
'db/*path': 'routeToServer'
@ -26,7 +31,7 @@ module.exports = class CocoRouter extends Backbone.Router
home: -> @openRoute('home')
general: (name) ->
@openRoute(name)
editorModelView: (modelName, slugOrId, subview) ->
modulePrefix = "views/editor/#{modelName}/"
suffix = subview or (if slugOrId then 'edit' else 'home')
@ -87,6 +92,14 @@ module.exports = class CocoRouter extends Backbone.Router
view = @getView(route)
@cache[route] = view unless view and view.cache is false
return view
routeDirectly: (path, args) ->
path = "views/#{path}"
ViewClass = @tryToLoadModule path
return @showNotFound() if not ViewClass
view = new ViewClass({}, args...) # options, then any path fragment args
view.render()
@openView(view)
getView: (route, suffix='_view') ->
# iteratively breaks down the url pieces looking for the view
@ -119,7 +132,7 @@ module.exports = class CocoRouter extends Backbone.Router
view.render()
closeCurrentView: ->
window.currentModal?.hide()
window.currentModal?.hide?()
return unless window.currentView?
if window.currentView.cache
window.currentView.scrollY = window.scrollY

View file

@ -22,17 +22,17 @@ module.exports = class Tracker
return unless me and olark?
olark 'api.chat.updateVisitorStatus', snippet: ["User ID: #{me.id}"]
return if me.get("anonymous")
olark 'api.visitor.updateEmailAddress', emailAddress: me.get("email")
olark 'api.visitor.updateEmailAddress', emailAddress: me.get("email") if me.get('email')
olark 'api.chat.updateVisitorNickname', snippet: me.displayName()
updatePlayState: (level, session) ->
return unless olark?
link = "codecombat.com/play/level/#{level.get('slug') or level.id}?session=#{session.id}"
snippet = [
"#{link}"
"User ID: #{me.id}"
"Session ID: #{session.id}"
"Level: #{level.get('name')}"
]
olark 'api.chat.updateVisitorStatus', snippet: snippet

View file

@ -16,18 +16,18 @@ module.exports.genericFailure = (jqxhr) ->
error = module.exports.parseServerError(jqxhr.responseText)
message = error.message
message = error.property + ' ' + message if error.property
res = errorModalTemplate(
status:jqxhr.status
statusText:jqxhr.statusText
message: message
)
console.warn(jqxhr.status, jqxhr.statusText, error)
existingForm = $('.form-inline:visible:first')
existingForm = $('.form:visible:first')
if existingForm[0]
missingErrors = applyErrorsToForm(existingForm, [error])
for error in missingErrors
existingForm.append($('<div class="alert"></div>').text(error.message))
else
res = errorModalTemplate(
status:jqxhr.status
statusText:jqxhr.statusText
message: message
)
showErrorModal(res)
module.exports.backboneFailure = (model, jqxhr, options) ->

View file

@ -102,6 +102,7 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
unless script
console.warn "Couldn't find script for", scriptID, "from scripts", @scripts, "when restoring session scripts."
continue
continue if script.repeats # repeating scripts are not 'rerun'
@triggered.push(scriptID)
@ended.push(scriptID)
noteChain = @processScript(script)
@ -120,8 +121,8 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
@run() unless @worldLoading
destroy: ->
super()
@onEndAll()
super()
# TRIGGERERING NOTES
@ -131,7 +132,17 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
alreadyTriggered = script.id in @triggered
continue unless script.channel is channel
continue if alreadyTriggered and not script.repeats
continue if script.lastTriggered? and script.repeats is 'session'
continue if script.lastTriggered? and new Date().getTime() - script.lastTriggered < 1
continue if script.neverRun
if script.notAfter
for scriptID in script.notAfter
if scriptID in @triggered
script.neverRun = true
break
continue if script.neverRun
continue unless @scriptPrereqsSatisfied(script)
continue unless scriptMatchesEventPrereqs(script, event)
# everything passed!
@ -182,7 +193,7 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
# STARTING NOTES
run: =>
run: ->
# catch all for analyzing the current state and doing whatever needs to happen next
return if @scriptInProgress
@skipAhead()

View file

@ -33,7 +33,7 @@ module.exports = class SpritesScriptModule extends ScriptModule
spriteSayNote: (sprite, script) ->
return if @speakingSprites[sprite.id]
responses = sprite.say.responses
responses = [] unless script.skippable
responses = [] unless script.skippable or responses
for response in responses ? []
response.text = response.i18n?[me.lang()]?.text ? response.text
text = sprite.say.i18n?[me.lang()]?.text or sprite.say.text

View file

@ -29,7 +29,7 @@ module.exports = class SurfaceScriptModule extends ScriptModule
e = {}
e.pos = focus.target if _.isPlainObject focus.target
e.thangID = focus.target if _.isString focus.target
e.zoom = focus.zoom or 2.0
e.zoom = focus.zoom or 2.0 # TODO: test only doing this if e.pos, e.thangID, or focus.zoom?
e.duration = if focus.duration? then focus.duration else 1500
e.duration = 0 if instant
e.bounds = focus.bounds if focus.bounds?

View file

@ -0,0 +1,274 @@
SuperModel = require 'models/SuperModel'
LevelLoader = require 'lib/LevelLoader'
GoalManager = require 'lib/world/GoalManager'
God = require 'lib/God'
module.exports = class Simulator
constructor: ->
_.extend @, Backbone.Events
@trigger 'statusUpdate', 'Starting simulation!'
@retryDelayInSeconds = 10
@taskURL = '/queue/scoring'
fetchAndSimulateTask: =>
@trigger 'statusUpdate', 'Fetching simulation data!'
$.ajax
url: @taskURL
type: "GET"
error: @handleFetchTaskError
success: @setupSimulationAndLoadLevel
handleFetchTaskError: (errorData) =>
console.log "There were no games to score. Error: #{JSON.stringify errorData}"
console.log "Retrying in #{@retryDelayInSeconds}"
@trigger 'statusUpdate', 'There were no games to simulate! Trying again in 10 seconds.'
@simulateAnotherTaskAfterDelay()
simulateAnotherTaskAfterDelay: =>
retryDelayInMilliseconds = @retryDelayInSeconds * 1000
_.delay @fetchAndSimulateTask, retryDelayInMilliseconds
setupSimulationAndLoadLevel: (taskData) =>
@trigger 'statusUpdate', 'Setting up simulation!'
@task = new SimulationTask(taskData)
@supermodel = new SuperModel()
@god = new God maxWorkerPoolSize: 1, maxAngels: 1 # Start loading worker.
@levelLoader = new LevelLoader supermodel: @supermodel, levelID: @task.getLevelName(), sessionID: @task.getFirstSessionID(), headless: true
@levelLoader.once 'loaded-all', @simulateGame
simulateGame: =>
@trigger 'statusUpdate', 'All resources loaded, simulating!', @task.getSessions()
@assignWorldAndLevelFromLevelLoaderAndDestroyIt()
@setupGod()
try
@commenceSimulationAndSetupCallback()
catch err
console.log "There was an error in simulation(#{err}). Trying again in #{@retryDelayInSeconds} seconds"
@simulateAnotherTaskAfterDelay()
assignWorldAndLevelFromLevelLoaderAndDestroyIt: ->
@world = @levelLoader.world
@level = @levelLoader.level
@levelLoader.destroy()
@levelLoader = null
setupGod: ->
@god.level = @level.serialize @supermodel
@god.worldClassMap = @world.classMap
@setupGoalManager()
@setupGodSpells()
setupGoalManager: ->
@god.goalManager = new GoalManager @world
@god.goalManager.goals = @god.level.goals
@god.goalManager.goalStates = @manuallyGenerateGoalStates()
commenceSimulationAndSetupCallback: ->
@god.createWorld()
Backbone.Mediator.subscribeOnce 'god:new-world-created', @processResults, @
processResults: (simulationResults) ->
taskResults = @formTaskResultsObject simulationResults
@sendResultsBackToServer taskResults
sendResultsBackToServer: (results) =>
@trigger 'statusUpdate', 'Simulation completed, sending results back to server!'
console.log "Sending result back to server!"
$.ajax
url: "/queue/scoring"
data: results
type: "PUT"
success: @handleTaskResultsTransferSuccess
error: @handleTaskResultsTransferError
complete: @cleanupAndSimulateAnotherTask
handleTaskResultsTransferSuccess: (result) =>
console.log "Task registration result: #{JSON.stringify result}"
@trigger 'statusUpdate', 'Results were successfully sent back to server!'
handleTaskResultsTransferError: (error) =>
@trigger 'statusUpdate', 'There was an error sending the results back to the server.'
console.log "Task registration error: #{JSON.stringify error}"
cleanupAndSimulateAnotherTask: =>
@cleanupSimulation()
@fetchAndSimulateTask()
cleanupSimulation: ->
@god.destroy()
@god = null
@world = null
@level = null
formTaskResultsObject: (simulationResults) ->
taskResults =
taskID: @task.getTaskID()
receiptHandle: @task.getReceiptHandle()
originalSessionID: @task.getFirstSessionID()
originalSessionRank: -1
calculationTime: 500
sessions: []
for session in @task.getSessions()
sessionResult =
sessionID: session.sessionID
submitDate: session.submitDate
creator: session.creator
metrics:
rank: @calculateSessionRank session.sessionID, simulationResults.goalStates, @task.generateTeamToSessionMap()
if session.sessionID is taskResults.originalSessionID
taskResults.originalSessionRank = sessionResult.metrics.rank
taskResults.originalSessionTeam = session.team
taskResults.sessions.push sessionResult
return taskResults
calculateSessionRank: (sessionID, goalStates, teamSessionMap) ->
humansDestroyed = goalStates["destroy-humans"].status is "success"
ogresDestroyed = goalStates["destroy-ogres"].status is "success"
if humansDestroyed is ogresDestroyed
return 0
else if humansDestroyed and teamSessionMap["ogres"] is sessionID
return 0
else if humansDestroyed and teamSessionMap["ogres"] isnt sessionID
return 1
else if ogresDestroyed and teamSessionMap["humans"] is sessionID
return 0
else
return 1
manuallyGenerateGoalStates: ->
goalStates =
"destroy-humans":
keyFrame: 0
killed:
"Human Base": false
status: "incomplete"
"destroy-ogres":
keyFrame:0
killed:
"Ogre Base": false
status: "incomplete"
setupGodSpells: ->
@generateSpellsObject()
@god.spells = @spells
generateSpellsObject: ->
@currentUserCodeMap = @task.generateSpellKeyToSourceMap()
@spells = {}
for thang in @level.attributes.thangs
continue if @thangIsATemplate thang
@generateSpellKeyToSourceMapPropertiesFromThang thang
thangIsATemplate: (thang) ->
for component in thang.components
continue unless @componentHasProgrammableMethods component
for methodName, method of component.config.programmableMethods
return true if @methodBelongsToTemplateThang method
return false
componentHasProgrammableMethods: (component) -> component.config? and _.has component.config, 'programmableMethods'
methodBelongsToTemplateThang: (method) -> typeof method is 'string'
generateSpellKeyToSourceMapPropertiesFromThang: (thang) =>
for component in thang.components
continue unless @componentHasProgrammableMethods component
for methodName, method of component.config.programmableMethods
spellKey = @generateSpellKeyFromThangIDAndMethodName thang.id, methodName
@createSpellAndAssignName spellKey, methodName
@createSpellThang thang, method, spellKey
@transpileSpell thang, spellKey, methodName
generateSpellKeyFromThangIDAndMethodName: (thang, methodName) ->
spellKeyComponents = [thang, methodName]
spellKeyComponents[0] = _.string.slugify spellKeyComponents[0]
spellKey = spellKeyComponents.join '/'
spellKey
createSpellAndAssignName: (spellKey, spellName) ->
@spells[spellKey] ?= {}
@spells[spellKey].name = spellName
createSpellThang: (thang, method, spellKey) ->
@spells[spellKey].thangs ?= {}
@spells[spellKey].thangs[thang.id] ?= {}
@spells[spellKey].thangs[thang.id].aether = @createAether @spells[spellKey].name, method
transpileSpell: (thang, spellKey, methodName) ->
slugifiedThangID = _.string.slugify thang.id
source = @currentUserCodeMap[[slugifiedThangID,methodName].join '/'] ? ""
@spells[spellKey].thangs[thang.id].aether.transpile source
createAether: (methodName, method) ->
aetherOptions =
functionName: methodName
protectAPI: false
includeFlow: false
#includeFlow: true
requiresThis: true
yieldConditionally: false
problems:
jshint_W040: {level: "ignore"}
jshint_W030: {level: "ignore"} # aether_NoEffect instead
aether_MissingThis: {level: 'error'}
#functionParameters: # TODOOOOO
if methodName is 'hear'
aetherOptions.functionParameters = ['speaker', 'message', 'data']
#console.log "creating aether with options", aetherOptions
return new Aether aetherOptions
class SimulationTask
constructor: (@rawData) ->
console.log 'Simulating sessions', (session for session in @getSessions())
getLevelName: ->
levelName = @rawData.sessions?[0]?.levelID
return levelName if levelName?
@throwMalformedTaskError "The level name couldn't be deduced from the task."
generateTeamToSessionMap: ->
teamSessionMap = {}
for session in @rawData.sessions
@throwMalformedTaskError "Two players share the same team" if teamSessionMap[session.team]?
teamSessionMap[session.team] = session.sessionID
teamSessionMap
throwMalformedTaskError: (errorString) ->
throw new Error "The task was malformed, reason: #{errorString}"
getFirstSessionID: -> @rawData.sessions[0].sessionID
getTaskID: -> @rawData.taskID
getReceiptHandle: -> @rawData.receiptHandle
getSessions: -> @rawData.sessions
generateSpellKeyToSourceMap: ->
spellKeyToSourceMap = {}
for session in @rawData.sessions
teamSpells = session.teamSpells[session.team]
teamCode = {}
for thangName, thangSpells of session.code
for spellName, spell of thangSpells
fullSpellName = [thangName,spellName].join '/'
if _.contains(teamSpells, fullSpellName)
teamCode[fullSpellName]=spell
_.merge spellKeyToSourceMap, teamCode
commonSpells = session.teamSpells["common"]
_.merge spellKeyToSourceMap, _.pick(session.code, commonSpells) if commonSpells?
spellKeyToSourceMap

View file

@ -3,7 +3,7 @@
module.exports = class SpriteBuilder
constructor: (@thangType, @options) ->
@options ?= {}
raw = _.cloneDeep(@thangType.get('raw'))
raw = @thangType.get('raw')
@shapeStore = raw.shapes
@containerStore = raw.containers
@animationStore = raw.animations
@ -124,7 +124,7 @@ module.exports = class SpriteBuilder
cont.addChild(child)
cont.bounds = new createjs.Rectangle(contData.b...)
cont
buildColorMaps: ->
@colorMap = {}
colorGroups = @thangType.get('colorGroups')
@ -136,15 +136,15 @@ module.exports = class SpriteBuilder
for group, config of colorConfig
continue unless colorGroups[group] # color group not found...
@buildColorMapForGroup(colorGroups[group], config)
buildColorMapForGroup: (shapes, config) ->
return unless shapes.length
colors = @initColorMap(shapes)
@adjustHuesForColorMap(colors, config.hue)
@adjustValueForColorMap(colors, 1, config.lightness)
@adjustValueForColorMap(colors, 2, config.saturation)
@adjustValueForColorMap(colors, 1, config.saturation)
@adjustValueForColorMap(colors, 2, config.lightness)
@applyColorMap(shapes, colors)
initColorMap: (shapes) ->
colors = {}
for shapeKey in shapes
@ -156,18 +156,18 @@ module.exports = class SpriteBuilder
adjustHuesForColorMap: (colors, targetHue) ->
hues = (hsl[0] for hex, hsl of colors)
# 'rotate' the hue spectrum so averaging works
if Math.max(hues) - Math.min(hues) > 0.5
hues = (if h < 0.5 then h + 1.0 else h for h in hues)
averageHue = sum(hues) / hues.length
averageHue %= 1
# end result should be something like a hue array of [0.9, 0.3] gets an average of 0.1
targetHue ?= 0
diff = targetHue - averageHue
hsl[0] = (hsl[0] + diff + 1) % 1 for hex, hsl of colors
adjustValueForColorMap: (colors, index, targetValue) ->
values = (hsl[index] for hex, hsl of colors)
averageValue = sum(values) / values.length
@ -183,4 +183,4 @@ module.exports = class SpriteBuilder
@colorMap[shapeKey] = hslToHex(colors[shape.fc])
sum = (nums) -> _.reduce(nums, (s, num) -> s + num)
sum = (nums) -> _.reduce(nums, (s, num) -> s + num)

View file

@ -11,5 +11,5 @@ module.exports.load = (key) ->
module.exports.save = (key, value) ->
s = JSON.stringify(value)
localStorage.setItem(key, s)
module.exports.remove = (key) -> localStorage.removeItem key
module.exports.remove = (key) -> localStorage.removeItem key

View file

@ -40,10 +40,13 @@ module.exports = class Camera extends CocoClass
'camera-zoom-out': 'onZoomOut'
'surface:mouse-scrolled': 'onMouseScrolled'
'level:restarted': 'onLevelRestarted'
'sprite:mouse-down': 'onMouseDown'
'sprite:dragged': 'onMouseDragged'
# TODO: Fix tests to not use mainLayer
constructor: (@canvasWidth, @canvasHeight, angle=Math.asin(0.75), hFOV=d2r(30)) ->
super()
@offset = {x: 0, y:0}
@calculateViewingAngle angle
@calculateFieldOfView hFOV
@calculateAxisConversionFactors()
@ -148,19 +151,48 @@ module.exports = class Camera extends CocoClass
onMouseScrolled: (e) ->
ratio = 1 + 0.05 * Math.sqrt(Math.abs(e.deltaY))
ratio = 1 / ratio if e.deltaY > 0
@zoomTo @target, @zoom * ratio, 0
newZoom = @zoom * ratio
if e.surfacePos and not @focusedOnSprite()
# zoom based on mouse position, adjusting the target so the point under the mouse stays the same
mousePoint = @canvasToSurface(e.surfacePos)
ratioPosX = (mousePoint.x - @surfaceViewport.x) / @surfaceViewport.width
ratioPosY = (mousePoint.y - @surfaceViewport.y) / @surfaceViewport.height
newWidth = @canvasWidth / newZoom
newHeight = @canvasHeight / newZoom
newTargetX = mousePoint.x - (newWidth * ratioPosX) + (newWidth / 2)
newTargetY = mousePoint.y - (newHeight * ratioPosY) + (newHeight / 2)
target = {x: newTargetX, y:newTargetY}
else
target = @target
@zoomTo target, newZoom, 0
onMouseDown: (e) ->
return if @dragDisabled
@lastPos = {x: e.originalEvent.rawX, y: e.originalEvent.rawY}
onMouseDragged: (e) ->
return if @dragDisabled
target = @boundTarget(@target, @zoom)
newPos = {
x: target.x + (@lastPos.x - e.originalEvent.rawX) / @zoom
y: target.y + (@lastPos.y - e.originalEvent.rawY) / @zoom
}
@zoomTo newPos, @zoom, 0
@lastPos = {x: e.originalEvent.rawX, y: e.originalEvent.rawY}
Backbone.Mediator.publish 'camera:dragged'
onLevelRestarted: ->
@setBounds(@firstBounds)
@setBounds(@firstBounds, false)
# COMMANDS
setBounds: (worldBounds) ->
setBounds: (worldBounds, updateZoom=true) ->
# receives an array of two world points. Normalize and apply them
@firstBounds = worldBounds unless @firstBounds
@bounds = @normalizeBounds(worldBounds)
@calculateMinZoom()
@updateZoom true
@target = @currentTarget unless @target.name
@updateZoom true if updateZoom
@target = @currentTarget unless @focusedOnSprite()
normalizeBounds: (worldBounds) ->
return null unless worldBounds
@ -186,8 +218,18 @@ module.exports = class Camera extends CocoClass
# Target is either just a {x, y} pos or a display object with {x, y} that might change; surface coordinates.
time = 0 if @instant
newTarget ?= {x:0, y:0}
newTarget = (@newTarget or @target) if @locked
newTarget = (@newTarget or @target) if @locked
newZoom = Math.min((Math.max @minZoom, newZoom), MAX_ZOOM)
thangType = @target?.sprite?.thangType
if thangType
@offset = _.clone(thangType.get('positions')?.torso or {x: 0, y:0})
scale = thangType.get('scale') or 1
@offset.x *= scale
@offset.y *= scale
else
@offset = {x: 0, y:0}
return if @zoom is newZoom and newTarget is newTarget.x and newTarget.y is newTarget.y
@finishTween(true)
@ -199,19 +241,20 @@ module.exports = class Camera extends CocoClass
@tweenProgress = 0.01
createjs.Tween.get(@)
.to({tweenProgress: 1.0}, time, createjs.Ease.getPowInOut(3))
.call @onTweenEnd
.call @finishTween
else
@target = newTarget
@zoom = newZoom
@updateZoom true
onTweenEnd: => @finishTween()
focusedOnSprite: ->
return @target?.name
finishTween: (abort=false) =>
createjs.Tween.removeTweens(@)
return unless @newTarget
unless abort
unless abort is true
@target = @newTarget
@zoom = @newZoom
@newZoom = @oldZoom = @newTarget = @newTarget = @tweenProgress = null
@ -219,7 +262,7 @@ module.exports = class Camera extends CocoClass
updateZoom: (force=false) ->
# Update when we're focusing on a Thang, tweening, or forcing it, unless we're locked
return if (not force) and (@locked or (not @newTarget and not @target?.name))
return if (not force) and (@locked or (not @newTarget and not @focusedOnSprite()))
if @newTarget
t = @tweenProgress
@zoom = @oldZoom + t * (@newZoom - @oldZoom)
@ -237,8 +280,8 @@ module.exports = class Camera extends CocoClass
return pos unless @bounds
marginX = (@canvasWidth / zoom / 2)
marginY = (@canvasHeight / zoom / 2)
x = Math.min(Math.max(marginX + @bounds.x, pos.x), @bounds.x + @bounds.width - marginX)
y = Math.min(Math.max(marginY + @bounds.y, pos.y), @bounds.y + @bounds.height - marginY)
x = Math.min(Math.max(marginX + @bounds.x, pos.x + @offset.x), @bounds.x + @bounds.width - marginX)
y = Math.min(Math.max(marginY + @bounds.y, pos.y + @offset.y), @bounds.y + @bounds.height - marginY)
{x: x, y: y}
updateViewports: (target) ->
@ -260,3 +303,8 @@ module.exports = class Camera extends CocoClass
@locked = true
unlock: ->
@locked = false
destroy: ->
createjs.Tween.removeTweens @
@finishTween = null
super()

View file

@ -0,0 +1,81 @@
CocoClass = require 'lib/CocoClass'
module.exports = class CastingScreen extends CocoClass
subscriptions:
'tome:cast-spells': 'onCastingBegins'
'god:new-world-created': 'onCastingEnds'
'god:world-load-progress-changed': 'onWorldLoadProgressChanged'
constructor: (options) ->
super()
options ?= {}
@camera = options.camera
@layer = options.layer
console.error @toString(), "needs a camera." unless @camera
console.error @toString(), "needs a layer." unless @layer
@build()
onCastingBegins: -> @show()
onCastingEnds: -> @hide()
toString: -> "<CastingScreen>"
build: ->
@dimLayer = new createjs.Container()
@dimLayer.mouseEnabled = @dimLayer.mouseChildren = false
@dimLayer.layerIndex = -11
@dimLayer.addChild @dimScreen = new createjs.Shape()
@dimScreen.graphics.beginFill("rgba(0,0,0,0.5)").rect 0, 0, @camera.canvasWidth, @camera.canvasHeight
@dimLayer.alpha = 0
@layer.addChild @dimLayer
@dimLayer.addChild @makeProgressBar()
@dimLayer.addChild @makeCastingText()
onWorldLoadProgressChanged: (e) ->
if new Date().getTime() - @t0 > 500
createjs.Tween.removeTweens @progressBar
createjs.Tween.get(@progressBar).to({scaleX:e.progress}, 200)
makeProgressBar: ->
BAR_PIXEL_HEIGHT = 3
BAR_PCT_WIDTH = .75
pixelWidth = parseInt(@camera.canvasWidth * BAR_PCT_WIDTH)
pixelMargin = (@camera.canvasWidth - (@camera.canvasWidth * BAR_PCT_WIDTH)) / 2
barY = 3 * (@camera.canvasHeight / 5)
g = new createjs.Graphics()
g.beginFill(createjs.Graphics.getRGB(255,255, 255))
g.drawRoundRect(0,0,pixelWidth, BAR_PIXEL_HEIGHT, 3)
@progressBar = new createjs.Shape(g)
@progressBar.x = pixelMargin
@progressBar.y = barY
@progressBar.scaleX = 0
@dimLayer.addChild(@progressBar)
makeCastingText: ->
size = @camera.canvasHeight / 15
text = new createjs.Text("Casting", "#{size}px cursive", "#aaaaaa")
text.regX = text.getMeasuredWidth() / 2
text.regY = text.getMeasuredHeight() / 2
text.x = @camera.canvasWidth / 2
text.y = @camera.canvasHeight / 2
@text = text
return text
show: ->
return if @showing
@showing = true
@t0 = new Date().getTime()
@progressBar.scaleX = 0
@dimLayer.alpha = 0
createjs.Tween.removeTweens @dimLayer
createjs.Tween.get(@dimLayer).to({alpha:1}, 500)
hide: ->
return unless @showing
@showing = false
createjs.Tween.removeTweens @progressBar
createjs.Tween.removeTweens @dimLayer
createjs.Tween.get(@dimLayer).to({alpha:0}, 500)

View file

@ -4,6 +4,7 @@ Camera = require './Camera'
Mark = require './Mark'
Label = require './Label'
AudioPlayer = require 'lib/AudioPlayer'
{me} = require 'lib/auth'
# We'll get rid of this once level's teams actually have colors
healthColors =
@ -64,26 +65,29 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
@age = 0
@displayObject = new createjs.Container()
if @thangType.get('actions')
@onThangTypeLoaded()
@setupSprite()
else
@stillLoading = true
@thangType.fetch()
@thangType.once 'sync', @onThangTypeLoaded, @
@thangType.once 'sync', @setupSprite, @
onThangTypeLoaded: ->
setupSprite: ->
@stillLoading = false
@actions = @thangType.getActions()
@buildFromSpriteSheet @buildSpriteSheet()
destroy: ->
super()
mark.destroy() for name, mark of @marks
label.destroy() for name, label of @labels
@imageObject?.off 'animationend', @playNextAction
@playNextAction = null
@displayObject?.off()
super()
toString: -> "<CocoSprite: #{@thang?.id}>"
buildSpriteSheet: ->
options = @thang?.getSpriteOptions?() or {}
options = _.extend @options, @thang?.getSpriteOptions?() ? {}
options.colorConfig = @options.colorConfig if @options.colorConfig
options.async = false
@thangType.getSpriteSheet options
@ -97,6 +101,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
# temp, until these are re-exported with perspective
if @options.camera and @thangType.get('name') in ['Dungeon Floor', 'Indoor Floor', 'Grass', 'Goal Trigger', 'Obstacle']
sprite.scaleY *= @options.camera.y2x
@displayObject.removeChild(@imageObject) if @imageObject
@imageObject = sprite
@displayObject.addChild(sprite)
@addHealthBar()
@ -107,7 +112,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
@displayObject.sprite = @
@displayObject.layerPriority = @thangType.get 'layerPriority'
@displayObject.name = @thang?.spriteName or @thangType.get 'name'
@imageObject.on 'animationend', @onActionEnd
@imageObject.on 'animationend', @playNextAction
##################################################
# QUEUEING AND PLAYING ACTIONS
@ -120,21 +125,24 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
@actionQueue.push @currentRootAction.relatedActions.end if @currentRootAction?.relatedActions?.end
@actionQueue.push action.relatedActions.begin if action.relatedActions?.begin
@actionQueue.push action
if action.goesTo and nextAction = @actions[action.goesTo]
@actionQueue.push nextAction if nextAction
@currentRootAction = action
@playNextAction()
onActionEnd: (e) => @playNextAction()
onSurfaceTicked: (e) -> @age += e.dt
playNextAction: ->
playNextAction: =>
@playAction(@actionQueue.splice(0,1)[0]) if @actionQueue.length
playAction: (action) ->
@currentAction = action
return @hide() unless action.animation or action.container or action.relatedActions
@show()
return @updateActionDirection() unless action.animation or action.container
m = if action.container then "gotoAndStop" else "gotoAndPlay"
@imageObject[m] action.name
@imageObject.framerate = action.framerate or 20
@imageObject[m] action.name
reg = @getOffset 'registration'
@imageObject.regX = -reg.x
@imageObject.regY = -reg.y
@ -142,6 +150,22 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
start = Math.floor(Math.random() * action.frames.length)
@imageObject.currentAnimationFrame = start
hide: ->
@hiding = true
@updateAlpha()
show: ->
@hiding = false
@updateAlpha()
stop: ->
@imageObject?.stop?()
mark.stop() for name, mark of @marks
play: ->
@imageObject?.play?()
mark.play() for name, mark of @marks
update: ->
# Gets the sprite to reflect what the current state of the thangs and surface are
return if @stillLoading
@ -153,6 +177,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
@updateStats()
@updateMarks()
@updateLabels()
@updateGold()
cache: ->
bounds = @imageObject.getBounds()
@ -181,16 +206,22 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
if @thang.width isnt @lastThangWidth or @thang.height isnt @lastThangHeight
[@lastThangWidth, @lastThangHeight] = [@thang.width, @thang.height]
bounds = @imageObject.getBounds()
@imageObject.scaleX = @thang.width * Camera.PPM / bounds.width * @thangType.get('scale') ? 1
@imageObject.scaleY = @thang.height * Camera.PPM * @options.camera.y2x / bounds.height * @thangType.get('scale') ? 1
@imageObject.scaleX = @thang.width * Camera.PPM / bounds.width
@imageObject.scaleY = @thang.height * Camera.PPM * @options.camera.y2x / bounds.height
unless @thang.spriteName is 'Beam'
@imageObject.scaleX *= @thangType.get('scale') ? 1
@imageObject.scaleY *= @thangType.get('scale') ? 1
return
scaleX = if @getActionProp 'flipX' then -1 else 1
scaleY = if @getActionProp 'flipY' then -1 else 1
scaleFactor = @thang.scaleFactor ? 1
@imageObject.scaleX = @originalScaleX * scaleX * scaleFactor
@imageObject.scaleY = @originalScaleY * scaleY * scaleFactor
scaleFactorX = @thang.scaleFactorX ? scaleFactor
scaleFactorY = @thang.scaleFactorY ? scaleFactor
@imageObject.scaleX = @originalScaleX * scaleX * scaleFactorX
@imageObject.scaleY = @originalScaleY * scaleY * scaleFactorY
updateAlpha: ->
@imageObject.alpha = if @hiding then 0 else 1
return unless @thang?.alpha?
@imageObject.alpha = @thang.alpha
if @options.showInvisible
@ -394,7 +425,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
sound = e.sound ? AudioPlayer.soundForDialogue e.message, @thangType.get 'soundTriggers'
@instance?.stop()
if @instance = @playSound sound, false
@instance.addEventListener "complete", => Backbone.Mediator.publish 'dialogue-sound-completed'
@instance.addEventListener "complete", -> Backbone.Mediator.publish 'dialogue-sound-completed'
@notifySpeechUpdated e
onClearDialogue: (e) ->
@ -414,9 +445,20 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
@notifySpeechUpdated blurb: blurb
label.update() for name, label of @labels
updateGold: ->
# TODO: eventually this should be moved into some sort of team-based update
# rather than an each-thang-that-shows-gold-per-team thing.
return if @thang.gold is @lastGold
gold = Math.floor @thang.gold
return if gold is @lastGold
@lastGold = gold
Backbone.Mediator.publish 'surface:gold-changed', {team: @thang.team, gold: gold}
playSounds: (withDelay=true, volume=1.0) ->
for event in @thang.currentEvents ? []
@playSound event, withDelay, volume
if event is 'pay-bounty-gold' and @thang.bountyGold > 25 and @thang.team isnt me.team
AudioPlayer.playInterfaceSound 'coin_1', 0.25
if @thang.actionActivated and (action = @thang.getActionName()) isnt 'say'
@playSound action, withDelay, volume
if @thang.sayMessage and withDelay # don't play sayMessages while scrubbing, annoying
@ -433,6 +475,6 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
return null unless sound
delay = if withDelay and sound.delay then 1000 * sound.delay / createjs.Ticker.getFPS() else 0
name = AudioPlayer.nameForSoundReference sound
instance = createjs.Sound.play name, "none", delay, 0, 0, volume
instance = AudioPlayer.playSound name, volume, delay
# console.log @thang?.id, "played sound", name, "with delay", delay, "volume", volume, "and got sound instance", instance
instance

View file

@ -12,11 +12,13 @@ module.exports = class CoordinateDisplay extends createjs.Container
@camera = options.camera
console.error "CoordinateDisplay needs camera." unless @camera
@build()
@show = _.debounce @show, 250
@show = _.debounce @show, 125
Backbone.Mediator.subscribe(channel, @[func], @) for channel, func of @subscriptions
destroy: ->
Backbone.Mediator.unsubscribe(channel, @[func], @) for channel, func of @subscriptions
@show = null
@destroyed = true
build: ->
@mouseEnabled = @mouseChildren = false
@ -46,14 +48,14 @@ module.exports = class CoordinateDisplay extends createjs.Container
@uncache()
show: =>
return unless @mouseInBounds and @lastPos
return unless @mouseInBounds and @lastPos and not @destroyed
@label.text = "(#{@lastPos.x}, #{@lastPos.y})"
[width, height] = [@label.getMeasuredWidth(), @label.getMeasuredHeight()]
@label.regX = width / 2
@label.regY = height / 2
sup = @camera.worldToSurface @lastPos
@x = sup.x
@y = sup.y
@y = sup.y - 7
@addChild @label
@cache -width / 2, -height / 2, width, height
Backbone.Mediator.publish 'surface:coordinates-shown', {}

View file

@ -21,9 +21,6 @@ module.exports = class Dimmer extends CocoClass
@highlightedThangIDs = []
@sprites = {}
destroy: ->
super()
toString: -> "<Dimmer>"
build: ->

View file

@ -22,6 +22,7 @@ module.exports = IndieSprite = class IndieSprite extends CocoSprite
thang.width = thang.height = thang.depth = 4
thang.pos = pos ? @defaultPos()
thang.pos.z = thang.depth / 2
thang.shape = 'ellipsoid'
thang.rotation = 0
thang.action = 'idle'
thang.setAction = (action) -> thang.action = action

View file

@ -54,17 +54,19 @@ module.exports = class Label extends CocoClass
buildLabelOptions: ->
o = {}
st = {dialogue: 'D', say: 'S', name: 'N'}[@style]
o.marginX = {D: 5, S: 2, N: 3}[st]
o.marginY = {D: 6, S: 2, N: 3}[st]
o.marginX = {D: 5, S: 6, N: 3}[st]
o.marginY = {D: 6, S: 4, N: 3}[st]
o.fontWeight = {D: "bold", S: "bold", N: "bold"}[st]
o.shadow = {D: false, S: true, N: true}[st]
o.fontSize = {D: 25, S: 19, N: 14}[st]
o.shadowColor = {D: "#FFF", S: "#000", N: "#FFF"}[st]
o.fontSize = {D: 25, S: 12, N: 12}[st]
fontFamily = {D: "Arial", S: "Arial", N: "Arial"}[st]
o.fontDescriptor = "#{o.fontSize}px #{fontFamily}"
o.fontColor = {D: "#000", S: "#000", N: "#00a"}[st]
o.backgroundFillColor = {D: "white", S: "rgba(255, 255, 255, 0.2)", N: "rgba(255, 255, 255, 0.5)"}[st]
o.backgroundStrokeColor = {D: "black", S: "rgba(0, 0, 0, 0.2)", N: "rgba(0, 0, 0, 0.0)"}[st]
o.fontDescriptor = "#{o.fontWeight} #{o.fontSize}px #{fontFamily}"
o.fontColor = {D: "#000", S: "#FFF", N: "#00a"}[st]
o.backgroundFillColor = {D: "white", S: "rgba(0, 0, 0, 0.4)", N: "rgba(255, 255, 255, 0.5)"}[st]
o.backgroundStrokeColor = {D: "black", S: "rgba(0, 0, 0, .6)", N: "rgba(0, 0, 0, 0.0)"}[st]
o.backgroundStrokeStyle = {D: 2, S: 1, N: 1}[st]
o.backgroundBorderRadius = {D: 10, S: 5, N: 3}[st]
o.backgroundBorderRadius = {D: 10, S: 3, N: 3}[st]
o.layerPriority = {D: 10, S: 5, N: 5}[st]
maxWidth = {D: 300, S: 300, N: 180}[st]
maxWidth = Math.max @camera.canvasWidth / 2 - 100, maxWidth # Does this do anything?
@ -79,7 +81,7 @@ module.exports = class Label extends CocoClass
label.lineHeight = o.fontSize + 2
label.x = o.marginX
label.y = o.marginY
label.shadow = new createjs.Shadow "#FFF", 1, 1, 0 if o.shadow
label.shadow = new createjs.Shadow o.shadowColor, 1, 1, 0 if o.shadow
label.layerPriority = o.layerPriority
label.name = "Sprite Label - #{@style}"
o.textHeight = label.getMeasuredHeight()

View file

@ -69,7 +69,7 @@ module.exports = class Layer extends createjs.Container
bz = if b.z then b.z else 1000
if az == bz
return 0 unless a.sprite?.thang?.pos and b.sprite?.thang?.pos
return b.sprite.thang.pos.y - a.sprite.thang.pos.y
return (b.sprite.thang.pos.y - a.sprite.thang.pos.y) or (b.sprite.thang.pos.x - a.sprite.thang.pos.x)
return az - bz
onZoomUpdated: (e) ->

View file

@ -19,6 +19,8 @@ module.exports = class Mark extends CocoClass
destroy: ->
@mark?.parent?.removeChild @mark
@markSprite?.destroy()
@sprite = null
super()
toString: -> "<Mark #{@name}: Sprite #{@sprite?.thang?.id ? 'None'}>"
@ -46,7 +48,7 @@ module.exports = class Mark extends CocoClass
build: ->
unless @mark
if @name is 'bounds' then @buildBounds()
else if @name is 'shadow' then @buildRadius()
else if @name is 'shadow' then @buildShadow()
else if @name is 'debug' then @buildDebug()
else if @thangType then @buildSprite()
else console.error "Don't know how to build mark for", @name
@ -85,21 +87,31 @@ module.exports = class Mark extends CocoClass
@lastWidth = @sprite.thang.width
@lastHeight = @sprite.thang.height
buildRadius: ->
# TODO: make this not just a shadow
# TODO: draw boxes and ellipses for non-circular Thangs
diameter = @sprite.thangType.get('shadow') ? @sprite.thang?.width + 0.5
diameter *= Camera.PPM
buildShadow: ->
width = (@sprite.thang?.width ? 0) + 0.5
height = (@sprite.thang?.height ? 0) + 0.5
longest = Math.max width, height
actualLongest = @sprite.thangType.get('shadow') ? longest
width = width * actualLongest / longest
height = height * actualLongest / longest
width *= Camera.PPM
height *= Camera.PPM * @camera.y2x # TODO: doesn't work with rotation
@mark = new createjs.Shape()
@mark.mouseEnabled = false
@mark.graphics.beginFill "black"
@mark.graphics.drawEllipse 0, 0, diameter, diameter * @camera.y2x
if @sprite.thang.shape in ['ellipsoid', 'disc']
@mark.graphics.drawEllipse 0, 0, width, height
else
@mark.graphics.drawRect 0, 0, width, height
@mark.graphics.endFill()
@mark.regX = diameter / 2
@mark.regY = diameter / 2 * @camera.y2x
@mark.regX = width / 2
@mark.regY = height / 2
@mark.layerIndex = 10
#@mark.cache 0, 0, diameter, diameter # not actually faster than simple ellipse draw
buildRadius: ->
return # not implemented
buildDebug: ->
@mark = new createjs.Shape()
PX = 3
@ -119,6 +131,7 @@ module.exports = class Mark extends CocoClass
markSprite = new CocoSprite @thangType, @thangType.spriteOptions
markSprite.queueAction 'idle'
@mark = markSprite.displayObject
@markSprite = markSprite
update: (pos=null) ->
return false unless @on
@ -149,7 +162,7 @@ module.exports = class Mark extends CocoClass
@mark.y += offset.y
updateRotation: ->
if @name is 'debug'
if @name is 'debug' or (@name is 'shadow' and @sprite.thang?.shape in ["rectangle", "box"])
@mark.rotation = @sprite.thang.rotation * 180 / Math.PI
updateScale: ->
@ -171,3 +184,6 @@ module.exports = class Mark extends CocoClass
@mark.scaleX = @mark.scaleY = Math.min 1, scale
if @name in ['selection', 'target', 'repair']
@mark.scaleY *= @camera.y2x # code applies perspective
stop: -> @markSprite?.stop()
play: -> @markSprite?.play()

View file

@ -7,14 +7,14 @@ CROSSFADE_LENGTH = 1500
module.exports = class MusicPlayer extends CocoClass
currentMusic: null
standingBy: null
subscriptions:
'level-play-music': 'onPlayMusic'
'audio-player:loaded': 'onAudioLoaded'
constructor: ->
super(arguments...)
me.on('change:music', @onMusicSettingChanged, @)
super arguments...
me.on 'change:music', @onMusicSettingChanged, @
onAudioLoaded: ->
@onPlayMusic(@standingBy) if @standingBy
@ -29,12 +29,12 @@ module.exports = class MusicPlayer extends CocoClass
AudioPlayer.preloadSound(src)
@standingBy = e
return
@standingBy = null
if @currentMusic
f = -> @stop()
createjs.Tween.get(@currentMusic).to({volume:0.0}, CROSSFADE_LENGTH).call(f)
@currentMusic = createjs.Sound.play(src, 'none', 0, 0, -1, 0.3) if src and e.play
return unless @currentMusic
@currentMusic.volume = 0.0
@ -48,4 +48,8 @@ module.exports = class MusicPlayer extends CocoClass
return unless @currentMusic
createjs.Tween.removeTweens(@currentMusic)
@currentMusic.volume = if me.get('music') then 1.0 else 0.0
destroy: ->
me.off 'change:music', @onMusicSettingChanged, @
super()

View file

@ -0,0 +1,40 @@
CocoClass = require 'lib/CocoClass'
module.exports = class PlaybackoverScreen extends CocoClass
constructor: (options) ->
super()
options ?= {}
@camera = options.camera
@layer = options.layer
console.error @toString(), "needs a camera." unless @camera
console.error @toString(), "needs a layer." unless @layer
@build()
toString: -> "<PlaybackoverScreen>"
build: ->
@dimLayer = new createjs.Container()
@dimLayer.mouseEnabled = @dimLayer.mouseChildren = false
@dimLayer.layerIndex = -12
@dimLayer.addChild @dimScreen = new createjs.Shape()
@dimScreen.graphics.beginFill("rgba(0,0,0,0.4)").rect 0, 0, @camera.canvasWidth, @camera.canvasHeight
@dimLayer.cache 0, 0, @camera.canvasWidth, @camera.canvasHeight
@dimLayer.alpha = 0
@layer.addChild @dimLayer
show: ->
console.log 'show playback over screen', @showing
return if @showing
@showing = true
@dimLayer.alpha = 0
createjs.Tween.removeTweens @dimLayer
createjs.Tween.get(@dimLayer).to({alpha:1}, 500)
hide: ->
console.log 'hide playback over screen', @showing
return unless @showing
@showing = false
createjs.Tween.removeTweens @dimLayer
createjs.Tween.get(@dimLayer).to({alpha:0}, 500)

View file

@ -5,10 +5,11 @@ module.exports = class PointChooser extends CocoClass
super()
@buildShape()
@options.stage.addEventListener 'stagemousedown', @onMouseDown
@options.camera.dragDisabled = true
destroy: ->
super()
@options.stage.removeEventListener 'stagemousedown', @onMouseDown
super()
# Called also from WorldSelectModal
setPoint: (@point) ->

View file

@ -7,12 +7,13 @@ module.exports = class RegionChooser extends CocoClass
@options.stage.addEventListener 'stagemousedown', @onMouseDown
@options.stage.addEventListener 'stagemousemove', @onMouseMove
@options.stage.addEventListener 'stagemouseup', @onMouseUp
@options.camera.dragDisabled = true
destroy: ->
super()
@options.stage.removeEventListener 'stagemousedown', @onMouseDown
@options.stage.removeEventListener 'stagemousemove', @onMouseMove
@options.stage.removeEventListener 'stagemouseup', @onMouseUp
super()
onMouseDown: (e) =>
return unless key.shift

View file

@ -13,15 +13,19 @@ module.exports = class SpriteBoss extends CocoClass
'bus:player-left': 'onPlayerLeft'
'level-set-debug': 'onSetDebug'
'level-highlight-sprites': 'onHighlightSprites'
'sprite:mouse-down': 'onSpriteMouseDown'
'sprite:mouse-up': 'onSpriteMouseUp'
'surface:stage-mouse-down': 'onStageMouseDown'
'level-select-sprite': 'onSelectSprite'
'level-suppress-selection-sounds': 'onSuppressSelectionSounds'
'level-lock-select': 'onSetLockSelect'
'level:restarted': 'onLevelRestarted'
'god:new-world-created': 'onNewWorld'
'tome:cast-spells': 'onCastSpells'
'camera:dragged': 'onCameraDragged'
constructor: (@options) ->
super()
@dragged = 0
@options ?= {}
@camera = @options.camera
@surfaceLayer = @options.surfaceLayer
@ -34,10 +38,10 @@ module.exports = class SpriteBoss extends CocoClass
@spriteSheetCache = {}
destroy: ->
super()
@removeSprite sprite for thangID, sprite of @sprites
@targetMark?.destroy()
@selectionMark?.destroy()
super()
toString: -> "<SpriteBoss: #{@sprites.length} sprites>"
@ -87,7 +91,7 @@ module.exports = class SpriteBoss extends CocoClass
@selectionMark = new Mark name: 'selection', camera: @camera, layer: @spriteLayers["Ground"], thangType: @thangTypeFor("Selection")
createSpriteOptions: (options) ->
_.extend options, camera: @camera, resolutionFactor: 4, groundLayer: @spriteLayers["Ground"], textLayer: @surfaceTextLayer, floatingLayer: @spriteLayers["Floating"], markThangTypes: @markThangTypes(), spriteSheetCache: @spriteSheetCache, showInvisible: @options.showInvisible, world: @world
_.extend options, camera: @camera, resolutionFactor: 4, groundLayer: @spriteLayers["Ground"], textLayer: @surfaceTextLayer, floatingLayer: @spriteLayers["Floating"], markThangTypes: @markThangTypes(), spriteSheetCache: @spriteSheetCache, showInvisible: @options.showInvisible
createIndieSprites: (indieSprites, withWizards) ->
unless @indieSprites
@ -103,9 +107,14 @@ module.exports = class SpriteBoss extends CocoClass
unless thangType = @thangTypeFor indieSprite.thangType
console.warn "Need to convert #{indieSprite.id}'s ThangType #{indieSprite.thangType} to a ThangType reference. Until then, #{indieSprite.id} won't show up."
return
sprite = new IndieSprite thangType, @createSpriteOptions {thangID: indieSprite.id, pos: indieSprite.pos, sprites: @sprites}
sprite = new IndieSprite thangType, @createSpriteOptions {thangID: indieSprite.id, pos: indieSprite.pos, sprites: @sprites, colorConfig: indieSprite.colorConfig}
@addSprite sprite, sprite.thang.id
createOpponentWizard: (opponent) ->
# TODO: colorize name and cloud by team, colorize wizard by user's color config, level-specific wizard spawn points
sprite = @createWizardSprite thangID: opponent.id, name: opponent.name
sprite.targetPos = if opponent.team is 'ogres' then {x: 52, y: 52} else {x: 28, y: 28}
createWizardSprite: (options) ->
sprite = new WizardSprite @thangTypeFor("Wizard"), @createSpriteOptions(options)
@addSprite sprite, sprite.thang.id, @spriteLayers["Floating"]
@ -136,15 +145,17 @@ module.exports = class SpriteBoss extends CocoClass
addThangToSprites: (thang, layer=null) ->
return console.warn 'Tried to add Thang to the surface it already has:', thang.id if @sprites[thang.id]
thangType = _.find @options.thangTypes, (m) -> m.get('name') is thang.spriteName
sprite = new CocoSprite thangType, @createSpriteOptions thang: thang
options = @createSpriteOptions thang: thang
options.resolutionFactor = if thangType.get('kind') is 'Floor' then 2 else 4
sprite = new CocoSprite thangType, options
@addSprite sprite, null, layer
sprite.setDebug @debug
sprite
removeSprite: (sprite) ->
sprite.displayObject.parent.removeChild sprite.displayObject
sprite.destroy()
delete @sprites[sprite.thang.id]
sprite.destroy()
updateSounds: ->
sprite.playSounds() for thangID, sprite of @sprites # hmm; doesn't work for sprites which we didn't add yet in adjustSpriteExistence
@ -174,6 +185,11 @@ module.exports = class SpriteBoss extends CocoClass
sprite.hasMoved = false
@removeSprite sprite if missing
@cache true if updateCache and @cached
# mainly for handling selecting thangs from session when the thang is not always in existence
if @willSelectThang and @sprites[@willSelectThang[0]]
@selectThang @willSelectThang...
@willSelectThang = null
cache: (update=false) ->
return if @cached and not update
@ -195,6 +211,22 @@ module.exports = class SpriteBoss extends CocoClass
spriteFor: (thangID) -> @sprites[thangID]
onNewWorld: (e) ->
@world = @options.world = e.world
@play()
onCastSpells: -> @stop()
play: ->
sprite.imageObject.play() for thangID, sprite of @sprites
@selectionMark?.play()
@targetMark?.play()
stop: ->
sprite.imageObject.stop() for thangID, sprite of @sprites
@selectionMark?.stop()
@targetMark?.stop()
# Selection
onSuppressSelectionSounds: (e) -> @suppressSelectionSounds = e.suppress
@ -206,8 +238,13 @@ module.exports = class SpriteBoss extends CocoClass
onSelectSprite: (e) ->
@selectThang e.thangID, e.spellName
onSpriteMouseDown: (e) ->
onCameraDragged: ->
@dragged += 1
onSpriteMouseUp: (e) ->
return if key.shift and @options.choosing
return @dragged = 0 if @dragged > 3
@dragged = 0
sprite = if e.sprite?.thang?.isSelectable then e.sprite else null
@selectSprite e, sprite
@ -216,9 +253,10 @@ module.exports = class SpriteBoss extends CocoClass
@selectSprite e if e.onBackground
selectThang: (thangID, spellName=null) ->
return @willSelectThang = [thangID, spellName] unless @sprites[thangID]
@selectSprite null, @sprites[thangID], spellName
selectSprite: (e, sprite=null, spellName=null) =>
selectSprite: (e, sprite=null, spellName=null) ->
return if e and (@disabled or @selectLocked) # Ignore clicks for selection/panning/wizard movement while disabled or select is locked
worldPos = sprite?.thang?.pos
worldPos ?= @camera.canvasToWorld {x: e.originalEvent.rawX, y: e.originalEvent.rawY} if e
@ -248,8 +286,12 @@ module.exports = class SpriteBoss extends CocoClass
# Marks
updateSelection: ->
if @selectedSprite?.thang and (not @selectedSprite.thang.exists or not @world.getThangByID @selectedSprite.thang.id)
@selectSprite null, null, null
@selectionMark?.toggle false
@updateTarget()
return unless @selectionMark
@selectedSprite = null unless @selectedSprite?.thang
@selectionMark.toggle @selectedSprite?
@selectionMark.setSprite @selectedSprite
@selectionMark.update()

View file

@ -8,6 +8,8 @@ CameraBorder = require './CameraBorder'
Layer = require './Layer'
Letterbox = require './Letterbox'
Dimmer = require './Dimmer'
CastingScreen = require './CastingScreen'
PlaybackOverScreen = require './PlaybackOverScreen'
DebugDisplay = require './DebugDisplay'
CoordinateDisplay = require './CoordinateDisplay'
SpriteBoss = require './SpriteBoss'
@ -46,6 +48,7 @@ module.exports = Surface = class Surface extends CocoClass
coords: true
playJingle: false
showInvisible: false
frameRate: 60 # Best as a divisor of 60, like 15, 30, 60, with RAF_SYNCHED timing.
subscriptions:
'level-disable-controls': 'onDisableControls'
@ -79,16 +82,31 @@ module.exports = Surface = class Surface extends CocoClass
@initAudio()
destroy: ->
super()
@dead = true
@camera?.destroy()
createjs.Ticker.removeEventListener("tick", @tick)
createjs.Sound.stop()
layer.destroy() for layer in @layers
@spriteBoss.destroy()
@chooser?.destroy()
@dimmer?.destroy()
@castingScreen?.destroy()
@playbackOverScreen?.destroy()
@stage.clear()
@musicPlayer?.destroy()
@stage.removeAllChildren()
@stage.removeEventListener 'stagemousemove', @onMouseMove
@stage.removeEventListener 'stagemousedown', @onMouseDown
@stage.removeAllEventListeners()
@stage.enableDOMEvents false
@stage.enableMouseOver 0
@onFramesScrubbed = null
@onMouseMove = null
@onMouseDown = null
@tick = null
@canvas.off 'mousewheel', @onMouseWheel
@onMouseWheel = null
super()
setWorld: (@world) ->
@worldLoaded = true
@ -163,7 +181,7 @@ module.exports = Surface = class Surface extends CocoClass
container.addChild shape
setProgress: (progress, scrubDuration=500) ->
progress = Math.max(Math.min(progress, 0.99), 0.0)
progress = Math.max(Math.min(progress, 1), 0.0)
@scrubbing = true
onTweenEnd = =>
@ -177,44 +195,45 @@ module.exports = Surface = class Surface extends CocoClass
createjs.Tween.removeTweens(@)
@currentFrame = @scrubbingTo
@scrubbingTo = parseInt(progress * @world.totalFrames)
@scrubbingTo = Math.min(Math.floor(progress * @world.totalFrames), @world.totalFrames)
@scrubbingPlaybackSpeed = Math.sqrt(Math.abs(@scrubbingTo - @currentFrame) * @world.dt / (scrubDuration or 0.5))
if scrubDuration
t = createjs.Tween
.get(@)
.to({currentFrame:@scrubbingTo}, scrubDuration, createjs.Ease.sineInOut)
.call(onTweenEnd)
t.addEventListener('change', @playScrubbedSounds)
t.addEventListener('change', @onFramesScrubbed)
else
@currentFrame = @scrubbingTo
@playScrubbedSounds()
@onFramesScrubbed() # For performance, don't play these for instant transitions.
onTweenEnd()
@updateState true
@onFrameChanged()
playScrubbedSounds: (e) =>
# gotta play all the sounds, even when scrubbing!
rising = @currentFrame > @lastFrame
actualCurrentFrame = @currentFrame
tempFrame = if rising then Math.ceil(@lastFrame) else Math.floor(@lastFrame)
while true # temporary fix to stop cacophony
break if rising and tempFrame > actualCurrentFrame
break if (not rising) and tempFrame < actualCurrentFrame
@currentFrame = tempFrame
frame = @world.getFrame(@getCurrentFrame())
frame.restoreState()
for thangID, sprite of @spriteBoss.sprites
sprite.playSounds false, Math.max(0.05, Math.min(1, 1 / @scrubbingPlaybackSpeed))
tempFrame += if rising then 1 else -1
@currentFrame = actualCurrentFrame
onFramesScrubbed: (e) =>
if e
# Gotta play all the sounds when scrubbing (but not when doing an immediate transition).
rising = @currentFrame > @lastFrame
actualCurrentFrame = @currentFrame
tempFrame = if rising then Math.ceil(@lastFrame) else Math.floor(@lastFrame)
while true # temporary fix to stop cacophony
break if rising and tempFrame > actualCurrentFrame
break if (not rising) and tempFrame < actualCurrentFrame
@currentFrame = tempFrame
frame = @world.getFrame(@getCurrentFrame())
frame.restoreState()
for thangID, sprite of @spriteBoss.sprites
sprite.playSounds false, Math.max(0.05, Math.min(1, 1 / @scrubbingPlaybackSpeed))
tempFrame += if rising then 1 else -1
@currentFrame = actualCurrentFrame
# TODO: are these needed, or perhaps do they duplicate things?
@spriteBoss.update()
@restoreWorldState()
@spriteBoss.update true
@onFrameChanged()
getCurrentFrame: ->
return Math.max(0, Math.min(parseInt(@currentFrame), @world.totalFrames - 1))
return Math.max(0, Math.min(Math.floor(@currentFrame), @world.totalFrames - 1))
getProgress: -> @currentFrame / @world.totalFrames
@ -230,7 +249,7 @@ module.exports = Surface = class Surface extends CocoClass
target = null
@camera.setBounds e.bounds if e.bounds
@cameraBorder.updateBounds @camera.bounds
@camera.zoomTo target, e.zoom, e.duration
@camera.zoomTo target, e.zoom, e.duration # TODO: SurfaceScriptModule perhaps shouldn't assign e.zoom if not set
setDisabled: (@disabled) ->
@spriteBoss.disabled = @disabled
@ -248,14 +267,14 @@ module.exports = Surface = class Surface extends CocoClass
onSetLetterbox: (e) ->
@setDisabled e.on
onSetPlaying: (e) =>
onSetPlaying: (e) ->
@playing = (e ? {}).playing ? true
if @playing and @currentFrame >= (@world.totalFrames - 5)
@currentFrame = 0
if @fastForwarding and not @playing
@setProgress @currentFrame / @world.totalFrames
onSetTime: (e) =>
onSetTime: (e) ->
toFrame = @currentFrame
if e.time?
@worldLifespan = @world.totalFrames / @world.frameRate
@ -282,14 +301,36 @@ module.exports = Surface = class Surface extends CocoClass
frame: @currentFrame
world: @world
)
if @lastFrame < @world.totalFrames and @currentFrame >= @world.totalFrames
@spriteBoss.stop()
@playbackOverScreen.show()
@ended = true
Backbone.Mediator.publish 'surface:playback-ended'
else if @currentFrame < @world.totalFrames and @ended
@spriteBoss.play()
@playbackOverScreen.hide()
@ended = false
Backbone.Mediator.publish 'surface:playback-restarted'
@lastFrame = @currentFrame
onCastSpells: (event) ->
@casting = true
@wasPlayingWhenCastingBegan = @playing
Backbone.Mediator.publish 'level-set-playing', { playing: false }
createjs.Tween.removeTweens(@surfaceLayer)
createjs.Tween.get(@surfaceLayer).to({alpha:0.9}, 1000, createjs.Ease.getPowOut(4.0))
onNewWorld: (event) ->
return unless event.world.name is @world.name
@casting = false
# This has a tendency to break scripts that are waiting for playback to change when the level is loaded
# so only run it after the first world is created.
Backbone.Mediator.publish 'level-set-playing', { playing: @wasPlayingWhenCastingBegan } unless event.firstWorld
fastForwardTo = null
if @playing
fastForwardTo = Math.min event.world.firstChangedFrame, @currentFrame
@ -317,6 +358,7 @@ module.exports = Surface = class Surface extends CocoClass
@stage = new createjs.Stage(@canvas[0])
canvasWidth = parseInt(@canvas.attr('width'), 10)
canvasHeight = parseInt(@canvas.attr('height'), 10)
@camera?.destroy()
@camera = new Camera canvasWidth, canvasHeight
@layers.push @surfaceLayer = new Layer name: "Surface", layerPriority: 0, transform: Layer.TRANSFORM_SURFACE, camera: @camera
@layers.push @surfaceTextLayer = new Layer name: "Surface Text", layerPriority: 1, transform: Layer.TRANSFORM_SURFACE_TEXT, camera: @camera
@ -325,13 +367,15 @@ module.exports = Surface = class Surface extends CocoClass
@surfaceLayer.addChild @cameraBorder = new CameraBorder bounds: @camera.bounds
@screenLayer.addChild new Letterbox canvasWidth: canvasWidth, canvasHeight: canvasHeight
@spriteBoss = new SpriteBoss camera: @camera, surfaceLayer: @surfaceLayer, surfaceTextLayer: @surfaceTextLayer, world: @world, thangTypes: @options.thangTypes, choosing: @options.choosing, navigateToSelection: @options.navigateToSelection, showInvisible: @options.showInvisible
@castingScreen ?= new CastingScreen camera: @camera, layer: @screenLayer
@playbackOverScreen ?= new PlaybackOverScreen camera: @camera, layer: @screenLayer
@stage.enableMouseOver(10)
@stage.addEventListener 'stagemousemove', @onMouseMove
@stage.addEventListener 'stagemousedown', @onMouseDown
@hookUpZoomControls()
@canvas.on 'mousewheel', @onMouseWheel
@hookUpChooseControls() if @options.choosing
console.log "Setting fps", @world.frameRate unless @world.frameRate is 30
createjs.Ticker.setFPS @world.frameRate
createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNCHED
createjs.Ticker.setFPS @options.frameRate
showLevel: ->
return if @dead
@ -347,6 +391,9 @@ module.exports = Surface = class Surface extends CocoClass
createjs.Ticker.addEventListener "tick", @tick
Backbone.Mediator.publish 'level:started'
createOpponentWizard: (opponent) ->
@spriteBoss.createOpponentWizard opponent
initAudio: ->
@musicPlayer = new MusicPlayer()
@ -419,6 +466,7 @@ module.exports = Surface = class Surface extends CocoClass
# uh
onMouseMove: (e) =>
@mouseSurfacePos = {x:e.stageX, y:e.stageY}
return if @disabled
Backbone.Mediator.publish 'surface:mouse-moved', x: e.stageX, y: e.stageY
@ -427,12 +475,15 @@ module.exports = Surface = class Surface extends CocoClass
onBackground = not @stage.hitTest e.stageX, e.stageY
Backbone.Mediator.publish 'surface:stage-mouse-down', onBackground: onBackground, x: e.stageX, y: e.stageY, originalEvent: e
hookUpZoomControls: ->
@canvas.bind 'mousewheel', (e) =>
# https://github.com/brandonaaron/jquery-mousewheel
e.preventDefault()
return if @disabled
Backbone.Mediator.publish 'surface:mouse-scrolled', deltaX: e.deltaX, deltaY: e.deltaY unless @disabled
onMouseWheel: (e) =>
# https://github.com/brandonaaron/jquery-mousewheel
e.preventDefault()
return if @disabled
event =
deltaX: e.deltaX
deltaY: e.deltaY
surfacePos: @mouseSurfacePos
Backbone.Mediator.publish 'surface:mouse-scrolled', event unless @disabled
hookUpChooseControls: ->
chooserOptions = stage: @stage, surfaceLayer: @surfaceLayer, camera: @camera, restrictRatio: @options.choosing is 'ratio-region'
@ -444,44 +495,59 @@ module.exports = Surface = class Surface extends CocoClass
tick: (e) =>
# seems to be a bug where only one object can register with the Ticker...
oldFrame = @currentFrame
oldWorldFrame = Math.floor oldFrame
while true
Dropper.tick()
@trailmaster.tick() if @trailmaster
# Skip some frame updates unless we're playing and not at end (or we haven't drawn much yet)
frameAdvanced = (@playing and @currentFrame < @world.totalFrames) or @totalFramesDrawn < 2
++@currentFrame if frameAdvanced
@updateSpriteSounds() if frameAdvanced
@currentFrame += @world.frameRate / @options.frameRate if frameAdvanced and @playing
newWorldFrame = Math.floor @currentFrame
worldFrameAdvanced = newWorldFrame isnt oldWorldFrame
if worldFrameAdvanced
# Only restore world state when it will correspond to an integer WorldFrame, not interpolated frame.
@restoreWorldState()
oldWorldFrame = newWorldFrame
break unless Dropper.drop()
if frameAdvanced and not worldFrameAdvanced
# We didn't end the above loop on an integer frame, so do the world state update.
@restoreWorldState()
# these are skipped for dropped frames
@updateState @currentFrame isnt oldFrame
@drawCurrentFrame()
@drawCurrentFrame e
@onFrameChanged()
@updatePaths() if (@totalFramesDrawn % 2) is 0 or createjs.Ticker.getMeasuredFPS() > createjs.Ticker.getFPS() - 5
Backbone.Mediator.publish('surface:ticked', {dt: @world.dt})
@updatePaths() if (@totalFramesDrawn % 4) is 0 or createjs.Ticker.getMeasuredFPS() > createjs.Ticker.getFPS() - 5
Backbone.Mediator.publish('surface:ticked', {dt: 1 / @options.frameRate})
mib = @stage.mouseInBounds
if @mouseInBounds isnt mib
Backbone.Mediator.publish('surface:mouse-' + (if mib then "over" else "out"), {})
@mouseInBounds = mib
updateSpriteSounds: ->
restoreWorldState: ->
@world.getFrame(@getCurrentFrame()).restoreState()
current = Math.max(0, Math.min(@currentFrame, @world.totalFrames - 1))
if current - Math.floor(current) > 0.01
next = Math.ceil current
ratio = current % 1
@world.frames[next].restorePartialState ratio if next > 1
@spriteBoss.updateSounds()
updateState: (frameChanged) ->
# world state must have been restored in @updateSpriteSounds
# world state must have been restored in @restoreWorldState
@camera.updateZoom()
@spriteBoss.update frameChanged
@spriteBoss.update frameChanged unless @casting
@dimmer?.setSprites @spriteBoss.sprites
drawCurrentFrame: ->
drawCurrentFrame: (e) ->
++@totalFramesDrawn
@stage.update()
@stage.update e
# paths - TODO: move to SpriteBoss? but only update on frame drawing instead of on every frame update?
updatePaths: ->
return unless @options.paths
return if @casting
@hidePaths()
selectedThang = @spriteBoss.selectedSprite?.thang
return if @world.showPaths is 'never'

View file

@ -24,18 +24,20 @@ module.exports = class WizardSprite extends IndieSprite
constructor: (thangType, options) ->
if options?.isSelf
options.colorConfig = me.get('wizard')?.colorConfig or {}
options.colorConfig = _.cloneDeep(me.get('wizard')?.colorConfig) or {}
super thangType, options
@isSelf = options.isSelf
@targetPos = @thang.pos
if @isSelf
@setNameLabel me.displayName()
@setColorHue me.get('wizardColor1')
else if options.name
@setNameLabel options.name
makeIndieThang: (thangType, thangID, pos) ->
thang = super thangType, thangID, pos
thang.isSelectable = false
thang.bobHeight = 1.5
thang.bobHeight = 0.75
thang.bobTime = 2
thang.pos.z += thang.bobHeight
thang
@ -57,7 +59,12 @@ module.exports = class WizardSprite extends IndieSprite
onMeSynced: (e) ->
return unless @isSelf
@setNameLabel me.displayName() if @displayObject.visible # not if we hid the wiz
@setColorHue me.get('wizardColor1')
newColorConfig = me.get('wizard')?.colorConfig or {}
shouldUpdate = not _.isEqual(newColorConfig, @options.colorConfig)
@options.colorConfig = _.cloneDeep(newColorConfig)
if shouldUpdate
@setupSprite()
@playAction(@currentAction)
onSpriteSelected: (e) ->
return unless @isSelf
@ -183,7 +190,7 @@ module.exports = class WizardSprite extends IndieSprite
Takes into account whether the wizard is in transit or not, and the bobbing up and down.
Eventually will also adjust based on where other wizards are.
"""
@targetPos = @targetSprite.thang.pos if @targetSprite
@targetPos = @targetSprite.thang.pos if @targetSprite?.thang
pos = _.clone(@targetPos)
pos.z = @defaultPos().z + @getBobOffset()
@adjustPositionToSideOfTarget(pos) if @targetSprite # be off to the side depending on placement in world
@ -213,7 +220,7 @@ module.exports = class WizardSprite extends IndieSprite
targetPos.y += @spriteYOffset
faceTarget: ->
if @targetSprite
if @targetSprite?.thang
@pointToward(@targetSprite.thang.pos)
updateMarks: ->

View file

@ -46,7 +46,6 @@ module.exports.Trailmaster = class Trailmaster
clock: 0
constructor: (@camera) ->
@listener = (e) => @tick(e)
tick: ->
@clock += 1

View file

@ -15,7 +15,7 @@ module.exports = class GoalManager extends CocoClass
nextGoalID: 0
constructor: (@world) ->
constructor: (@world, @initialGoals) ->
super()
@init()
@ -25,6 +25,7 @@ module.exports = class GoalManager extends CocoClass
@userCodeMap = {} # @userCodeMap.thangID.methodName.aether.raw = codeString
@thangTeams = {}
@initThangTeams()
@addGoal goal for goal in @initialGoals if @initialGoals
initThangTeams: ->
return unless @world
@ -34,8 +35,6 @@ module.exports = class GoalManager extends CocoClass
@thangTeams[thang.team].push(thang.id)
subscriptions:
'level-add-goals': 'onAddGoals'
'level-remove-goals': 'onRemoveGoals'
'god:new-world-created': 'onNewWorldCreated'
'level:restarted': 'onLevelRestarted'
@ -46,25 +45,15 @@ module.exports = class GoalManager extends CocoClass
'world:thang-collected-item': 'onThangCollectedItem'
'world:ended': 'onWorldEnded'
onLevelRestarted: =>
onLevelRestarted: ->
@goals = []
@goalStates = {}
@userCodeMap = {}
@notifyGoalChanges()
@addGoal goal for goal in @initialGoals if @initialGoals
# INTERFACE AND LIFETIME OVERVIEW
# main instance receives goal updates from the script manager
onAddGoals: (e) =>
return unless e.worldName is @world.name
goals = e.goals
@addGoal(goal) for goal in goals
onRemoveGoals: (e) =>
if e.goal in @goals
@goals.remove(e.goal)
delete @goalStates[e.goal]
# world generator gets current goals from the main instance
getGoals: -> @goals
@ -79,7 +68,7 @@ module.exports = class GoalManager extends CocoClass
func = @backgroundSubscriptions[channel]
func = utils.normalizeFunc(func, @)
return unless func
func(event, frameNumber)
func.call(@, event, frameNumber)
# after world generation, generated goal states
# are grabbed to send back to main instance
@ -88,8 +77,9 @@ module.exports = class GoalManager extends CocoClass
# main instance gets them and updates their existing goal states,
# passes the word along
onNewWorldCreated: (e) =>
onNewWorldCreated: (e) ->
@updateGoalStates(e.goalStates) if e.goalStates?
@world = e.world
updateGoalStates: (newGoalStates) ->
for goalID, goalState of newGoalStates
@ -100,6 +90,7 @@ module.exports = class GoalManager extends CocoClass
# IMPLEMENTATION DETAILS
addGoal: (goal) ->
goal = _.cloneDeep(goal)
goal.id = @nextGoalID++ if not goal.id
return if @goalStates[goal.id]?
@goals.push(goal)
@ -134,48 +125,47 @@ module.exports = class GoalManager extends CocoClass
status: null # should eventually be either 'success', 'failure', or 'incomplete'
keyFrame: 0 # when it became a 'success' or 'failure'
}
@initGoalState(state, [goal.killThangs, goal.saveThangs], 'killed')
@initGoalState(state, [goal.getToLocations?.who, goal.keepFromLocations?.who], 'arrived')
@initGoalState(state, [goal.leaveOffSides?.who, goal.keepFromLeavingOffSides?.who], 'left')
@initGoalState(state, [goal.collectThangs?.who, goal.keepFromCollectingThangs?.who], 'collected')
@goalStates[goal.id] = state
onThangDied: (e, frameNumber) =>
onThangDied: (e, frameNumber) ->
for goal in @goals ? []
@checkKillThangs(goal.id, goal.killThangs, e.thang, frameNumber) if goal.killThangs?
@checkKillThangs(goal.id, goal.saveThangs, e.thang, frameNumber) if goal.saveThangs?
checkKillThangs: (goalID, targets, thang, frameNumber) =>
checkKillThangs: (goalID, targets, thang, frameNumber) ->
return unless thang.id in targets or thang.team in targets
@updateGoalState(goalID, thang.id, 'killed', frameNumber)
onThangTouchedGoal: (e, frameNumber) =>
onThangTouchedGoal: (e, frameNumber) ->
for goal in @goals ? []
@checkArrived(goal.id, goal.getToLocations.who, goal.getToLocations.targets, e.actor.id, e.touched.id, frameNumber) if goal.getToLocations?
@checkArrived(goal.id, goal.keepFromLocations.who, goal.keepFromLocations.targets, e.actor.id, e.touched.id, frameNumber) if goal.keepFromLocations?
@checkArrived(goal.id, goal.getToLocations.who, goal.getToLocations.targets, e.actor, e.touched.id, frameNumber) if goal.getToLocations?
@checkArrived(goal.id, goal.keepFromLocations.who, goal.keepFromLocations.targets, e.actor, e.touched.id, frameNumber) if goal.keepFromLocations?
checkArrived: (goalID, who, targets, thangID, touchedID, frameNumber) =>
checkArrived: (goalID, who, targets, thang, touchedID, frameNumber) ->
return unless touchedID in targets
return unless thangID in who
@updateGoalState(goalID, thangID, 'arrived', frameNumber)
return unless thang.id in who or thang.team in who
@updateGoalState(goalID, thang.id, 'arrived', frameNumber)
onThangLeftMap: (e, frameNumber) =>
onThangLeftMap: (e, frameNumber) ->
for goal in @goals ? []
@checkLeft(goal.id, goal.leaveOffSides.who, goal.leaveOffSides.sides, e.thang.id, e.side, frameNumber) if goal.leaveOffSides?
@checkLeft(goal.id, goal.keepFromLeavingOffSides.who, goal.keepFromLeavingOffSides.sides, e.thang.id, e.side, frameNumber) if goal.keepFromLeavingOffSides?
checkLeft: (goalID, who, sides, thangID, side, frameNumber) =>
checkLeft: (goalID, who, sides, thangID, side, frameNumber) ->
return if sides and side and not (side in sides)
return unless thangID in who
@updateGoalState(goalID, thangID, 'left', frameNumber)
onThangCollectedItem: (e, frameNumber) =>
onThangCollectedItem: (e, frameNumber) ->
for goal in @goals ? []
@checkCollected(goal.id, goal.collectThangs.who, goal.collectThangs.targets, e.actor.id, e.item.id, frameNumber) if goal.collectThangs?
@checkCollected(goal.id, goal.keepFromCollectingThangs.who, goal.keepFromCollectingThangs.targets, e.actor.id, e.item.id, frameNumber) if goal.keepFromCollectingThangs?
checkCollected: (goalID, who, targets, thangID, itemID, frameNumber) =>
checkCollected: (goalID, who, targets, thangID, itemID, frameNumber) ->
return unless itemID in targets
return unless thangID in who
@updateGoalState(goalID, thangID, 'collected', frameNumber)
@ -221,7 +211,7 @@ module.exports = class GoalManager extends CocoClass
stateThangs[thangID] = true
success = @goalIsPositive goalID
if success
numNeeded = Math.max((goal.howMany ? 1), _.size stateThangs)
numNeeded = goal.howMany ? Math.max(1, _.size stateThangs)
else
# saveThangs: by default we would want to save all the Thangs, which means that we would want none of them to be "done"
numNeeded = _.size(stateThangs) - Math.min((goal.howMany ? 1), _.size stateThangs) + 1

View file

@ -1,797 +0,0 @@
{me} = require('lib/auth')
# If we use marked somewhere else, we'll have to make sure to preserve options
marked.setOptions {gfm: true, sanitize: false, smartLists: true, breaks: true}
markedWithImages = (s) ->
s = s.replace /!\[(.*?)\]\((.+)? (\d+) (\d+) ?(.*?)?\)/g, '<img src="/images/docs/$2" alt="$1" title="$1" style="width: $3px; height: $4px;" class="$5"></img>' # setting width/height attrs doesn't prevent flickering, but inline css does
marked(s)
module.exports.getDocsFor = (thang, props, isSnippet=false) ->
docs = []
types = {}
for prop in props ? []
type = if isSnippet then 'snippet' else typeof thang[prop]
(types[type] ?= []).push prop
order = ["function", "object", "string", "number", "boolean", "undefined", "snippet"]
order.push type for type of types when not (type in order)
for type in order
for prop in (types[type] ? [])
docClass = if D.hasOwnProperty prop then D[prop] else Doc
docs.push new docClass(thang, prop, type)
docs
module.exports.hasLevelDocs = (levelID) ->
D[levelID]?
module.exports.getLevelDocs = (levelID, world) ->
levelDocsClass = D[levelID] ? Level
new levelDocsClass world
module.exports.Doc = class Doc
writable: false
owner: "this"
constructor: (@thang, @prop, @type) ->
if @owner isnt "this"
@type = typeof window[@owner][@prop]
@buildShortName()
buildShortName: ->
@shortName = @prop
if @type is 'function' then @shortName += "()"
if @type isnt 'snippet' then @shortName = "#{@owner}.#{@shortName}"
@shorterName = @shortName.replace 'this.', ''
@shortName += ';'
title: ->
typeStr = @type
if @type is 'function' and @owner is 'this'
typeStr = 'method'
if @type isnt 'function' and not @writable
typeStr += ' (read-only)'
nameStr = @shortName
"""<h4>#{nameStr} - <code class=\"prop-type\">#{typeStr}</code></h4>"""
html: ->
s = markedWithImages(@doc())
if @type in ['function', 'snippet']
exampleCode = @example()
if exampleCode.split('\n').length > 1
exampleCode = "```\n#{exampleCode}```"
else
exampleCode = "`#{exampleCode}`"
s += marked("**Example**:\n#{exampleCode}")
args = @args?() or []
if args.length
s += marked("**Arguments**:")
s += (arg.html() for arg in args).join('')
else
s += @value()
s
value: ->
"""
<strong>Current value</strong>:
<code class=\"current-value\" data-prop=\"#{@prop}\">#{@formatValue()}</code>
"""
doc: ->
"""
This does something. I think.
"""
example: ->
s = "#{@owner}.#{@shortName};"
if @type is 'function'
exampleArgs = (arg.example ? arg.default ? arg.name for arg in @args?() ? []).join ', '
s = "#{@owner}.#{@prop}(#{exampleArgs});"
s
formatValue: ->
if @owner is 'this'
v = @thang[@prop]
else
v = window[@owner][@prop]
if @type is 'number' and not isNaN v
if v == Math.round v
return v
return v.toFixed 2
if _.isString v
return "\"#{v}\""
v
module.exports.Arg = class Arg
constructor: (@name, @type, @example, @description, @default) ->
html: ->
s = "`#{@name}`: `#{@type}`"
if @example then s += " (ex: `#{@example}`)"
if @description then s += "\n#{@description}"
if @default? then s += "\n*Default value*: `#{@default}`"
marked s
module.exports.Level = class Level
constructor: (@world) ->
docID: (docName="doc") ->
"level-doc-#{docName}"
html: (docName="doc", title, buttons) ->
forVictory = docName is "victory"
docID = @docID docName
title ?= @world.name + (if forVictory then " Complete" else "")
docHTML = if @[docName] then markedWithImages(@[docName]()) else "No #{docName}. Wail!"
if forVictory
buttonHTML = @victoryButtons()
else
buttonHTML = @buttons(buttons ? ["I'm Ready."])
"""<div id="#{docID}" class="level-doc modal hide fade" tabindex="-1">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h3>#{title}</h3>
</div>
<div class="modal-body">
#{docHTML}
</div>
<div class="modal-footer">
#{buttonHTML}
</div>
</div>
"""
doc: ->
"""
Venusaur? Oh no, counterattack with whatever you feel like, man!
"""
victory: ->
"""
Detect it, it it no going and you tell me do things I done runnin'.
"""
buttons: (names) ->
buttonHTML = []
for name in names
buttonHTML.push(
"""
<button class="btn btn-primary" data-dismiss="modal">#{name}</button>
"""
)
buttonHTML.join ' '
victoryButtons: ->
buttons = """
<button id="victory-stay" data-dismiss="modal" class="btn">Stay A While</button>
<a href="/" class="btn">Go Home</a>
"""
if me.get 'anonymous'
buttons += """
<button class="btn btn-success sign-up-button">Sign Up for Updates</button>
"""
if @world.nextLevel
buttons += """
<a href="/play/level/#{@world.nextLevel}" class="btn btn-primary" data-dismiss="modal" >Next Level</a>
"""
buttons += """
<div class="share-buttons">
<div class="g-plusone" data-href="http://codecombat.com" data-size="medium"></div>
<div class="fb-like" data-href="http://codecombat.com" data-send="false" data-layout="button_count" data-width="350" data-show-faces="true"></div>
</div>
"""
buttons
D = {} # save typing for all these things
# Markdown: http://daringfireball.net/projects/markdown/syntax
# GitHub Flavored Markdown: https://help.github.com/articles/github-flavored-markdown
# Our Markdown parser and compiler: https://github.com/chjj/marked
# I have extended the img syntax to take width and height (preventing flicker).
D.ifElse = class IfElse extends Doc
buildShortName: ->
@shortName = @shorterName = "if/else"
doc: ->
"""
The `if` control statement lets you choose whether to run the following code based on whether the condition evaluates truthily.
You can add an optional `else` clause to run instead when the condition evaluates falsily.
"""
example: ->
"""
if(2 + 2 === 4) {
// Code here
}
else {
// Code here
}
"""
D.forLoop = class ForLoop extends Doc
buildShortName: ->
@shortName = @shorterName = "for-loop"
doc: ->
"""
The `for` loop lets you run code many times. It has four parts:
* initial setup: `var i = 0;` (run at the beginning)
* loop condition: `i < 10;` (code runs while this is true)
* loop iteration: `i += 1` (runs after every iteration)
* main loop code: `console.log("Counted to", i);`
"""
example: ->
"""
for(var i = 0; i < 10; i += 1) {
// Code here
}
"""
D.whileLoop = class WhileLoop extends Doc
buildShortName: ->
@shortName = @shorterName = "while-loop"
doc: ->
"""
The `while` loop lets you run code many times--as long as the condition is true.
"""
example: ->
"""
var i = 10;
while(i < 10) {
// Code here
i -= 1;
}
"""
D.rotateTo = class RotateTo extends Doc
doc: ->
"""
The `rotateTo` method rotates the #{@thang.spriteName}. ![Rotation of 0° points to the right, 90° points up, etc.](rotate.png 160 160)
Use this method to change the direction that the #{@thang.spriteName} shoots.
"""
args: ->
[new Arg "degrees", "number", "180", "Desired rotation in degrees"]
D.shoot = class Shoot extends Doc
doc: ->
"""
Calling `this.shoot();` makes the #{@thang.spriteName} choose the `shoot` action.
It's equivalent to: `this.setAction(this.actions.shoot);`
"""
D.pos = class Pos extends Doc
doc: ->
"""
The `x` (horizontal) and `y` (vertical) coordinates of the #{@thang.spriteName}'s center.
"""
D.rotation = class Rotation extends Doc
doc: ->
"""
The #{@thang.spriteName}'s rotation in radians (`0` to `2 * Math.PI`).
Use the `rotateTo` method to set this value.
"""
D.degrees = class Degrees extends Doc
doc: ->
"""
The #{@thang.spriteName}'s rotation in degrees (`0` to `360`).
Use the `rotateTo` method to set this value.
"""
D.attackRange = class AttackRange extends Doc
doc: ->
"""
How far the #{@thang.spriteName}'s attack reaches, in meters.
"""
D.health = class Health extends Doc
doc: ->
"""
How many health points the #{@thang.spriteName} has left.
"""
D.team = class Team extends Doc
doc: ->
"""
What team the #{@thang.spriteName} is on.
"""
D.actions = class Actions extends Doc
doc: ->
"""
The #{@thang.spriteName}'s available actions.
To, say, move, use: `this.setAction("move");`
"""
formatValue: () ->
v = @thang[@prop]
'[' + ("\"#{actionName}\"" for actionName of v).join(', ') + ']'
D.action = class Action extends Doc
doc: ->
"""
The current action the #{@thang.spriteName} is running.
To change this, use the `setAction` method.
"""
D.setAction = class SetAction extends Doc
doc: ->
"""
Sets the action that the #{@thang.spriteName} is running. Only actions in `this.actions` are valid.
"""
#For example, if `this.action` is currently `"idle"` and you want it to move instead, you'd set a target location, then: `this.setAction("move");`
args: ->
exampleAction = "idle"
for action in ["move", "shoot", "attack"]
if @thang.actions[action]
exampleAction = action
break
unless exampleAction
exampleAction = _.some @thang.actions, "name"
exampleAction = "\"#{exampleAction}\""
[new Arg "action", "object", exampleAction, "The action to perform (must be one of `this.actions`)."]
D.target = class Target extends Doc
doc: ->
"""
The current target upon which the #{@thang.spriteName} is running its `action`.
To change this, use the `setTarget` method.
"""
formatValue: () ->
v = @thang[@prop]
if v? then v.toString() else 'null'
D.setTarget = class SetTarget extends Doc
doc: ->
"""
Sets what the #{@thang.spriteName} is targeting with its current `action`, such as an enemy to attack or a position to move to.
"""
#For example, if `this.action` is currently `this.actions.move`, the #{@thang.spriteName} will move toward its `target`; if its action is `this.actions.attack`, it will try to attack its target.
#For some actions, you can also pass `x` and `y` coordinates as a target instead of another unit: `this.setTarget(65, 40);`
args: ->
exampleTarget = "65, 40"
for [methods, code] in [[["getNearestEnemy"], "this.getNearestEnemy()"],
[["pos", "move"], "this.pos.x + 20, this.pos.y - 20"],
[["attack"], "enemy"],
[["shoot"], "enemy"]]
if (m for m in methods when m in @thang.programmableProperties).length
exampleTarget = code
break
[new Arg "target", "object", exampleTarget, "The new target upon which to act."]
D.chooseAction = class ChooseAction extends Doc
doc: ->
"""
The `chooseAction` method is run every frame, allowing the #{@thang.spriteName} a chance to look at the world and decide what action to pursue this frame.
To see available actions, hover over the `actions` property below. To choose an action, say `attack`, you can write: `this.setAction(this.actions.attack);`
"""
D.plan = class Plan extends Doc
doc: ->
"""
The `plan` method (spell) is where you write a sequence of methods (spells) to command the #{@thang.spriteName}.
Type your methods into the Spell Editor below. Hover over your available methods at the bottom to see what they do.
"""
example: ->
"""
this.moveRight();
this.moveRight();
this.attackNearbyEnemy();
"""
D.attack = class Attack extends Doc
doc: ->
"""
The `attack` method takes an enemy `target`, sets the #{@thang.spriteName}'s `target` to that `target` with the `setTarget` method, and sets the #{@thang.spriteName}'s `action` to the `this.actions.attack` action with the `setAction` method.
"""
args: ->
exampleTarget = "enemy"
for [methods, code] in [[["getNearestEnemy"], "this.getNearestEnemy()"],
[["getEnemies"], "this.getEnemies()[0]"]]
if (m for m in methods when m in @thang.programmableProperties).length
exampleTarget = code
break
[new Arg "target", "object", exampleTarget, "The target enemy to attack."]
D.moveXY = class MoveXY extends Doc
doc: ->
"""
The `moveXY` method sets the #{@thang.spriteName}'s `targetPos` to the given `(x, y)` coordinates and also sets the #{@thang.spriteName}'s `action` to `move`.
"""
args: ->
[
new Arg "x", "number", "24", "The x coordinate toward which to move."
new Arg "y", "number", "35", "The y coordinate toward which to move."
]
D.distanceTo = class DistanceTo extends Doc
doc: ->
"""
Returns the distance in meters to the `target` unit from the center of the #{@thang.spriteName}.
"""
args: ->
exampleTarget = "enemy"
for [methods, code] in [#[["getNearestEnemy"], "this.getNearestEnemy()"],
[["getEnemies"], "this.getEnemies()[0]"],
[["getFriends"], "this.getFriends()[0]"]]
if (m for m in methods when m in @thang.programmableProperties).length
exampleTarget = code
break
[new Arg "target", "object", exampleTarget, "The target unit whose distance you want to measure."]
D.getEnemies = class GetEnemies extends Doc
doc: ->
"""
Returns an array of all living enemies within eyesight.
"""
example: ->
"""
var enemies = this.getEnemies();
for(var i = 0; i < enemies.length; ++i) {
var enemy = enemies[i];
// Do something with each enemy here
this.attack(enemy); // Example
}
"""
D.getFriends = class GetFriends extends Doc
doc: ->
"""
Returns an array of all living friends within eyesight.
"""
example: ->
"""
var friends = this.getFriends();
for(var i = 0; i < friends.length; ++i) {
var friend = friends[i];
// Do something with each friend here
this.follow(friend); // Example
}
"""
D.getItems = class GetItems extends Doc
doc: ->
"""
Returns an array of all living items within eyesight.
"""
example: ->
"""
var items = this.getItems()
for(var i = 0; i < items.length; ++i) {
var item = items[i];
// Do something with each item here
this.move(item.pos); // Example
}
"""
D.attackNearbyEnemy = class GetNearbyEnemy extends Doc
doc: ->
"""
Attacks any enemy within #{@thang.attackNearbyEnemyRange ? 5} meters of the #{@thang.spriteName}.
"""
D.getNearestEnemy = class GetNearestEnemy extends Doc
doc: ->
"""
Returns the closest living enemy, or `null` if there aren\'t any.
"""
example: ->
"""
var enemy = this.getNearestEnemy();
"""
D.getNearestFriend = class GetNearestFriend extends Doc
doc: ->
"""
Returns the closest living friend, or `null` if there aren\'t any.
"""
example: ->
"""
var friend = this.getNearestFriend();
"""
D.getNearestCombtaant = class GetNearestCombatant extends Doc
doc: ->
"""
Returns the closest living friend or foe, or `null` if there aren\'t any.
"""
example: ->
"""
var enemy = this.getNearestCombatant();
"""
D.attackXY = class AttackXY extends Doc
doc: ->
"""
The `attackXY` method makes the #{@thang.spriteName} attack the ground at the given `(x, y)` coordinates.
"""
args: ->
[
new Arg "x", "number", "24", "The x coordinate to attack."
new Arg "y", "number", "35", "The y coordinate to attack."
]
D.patrol = class Patrol extends Doc
doc: ->
"""
The `patrol` method causes the #{@thang.spriteName} to move between the given waypoints in a loop. When combined with code to `attack` nearby enemies, you can use it to guard an area.
"""
args: ->
[new Arg "patrolPoints", "array", "[{x: 15, y: 45}, {x: 30, y: 40}, {x: 25, y: 35}]", "An array of positions to move between."]
D.attackNearestEnemy = class AttackNearestEnemy extends Doc
doc: ->
"""
The `attackNearestEnemy` method causes the #{@thang.spriteName} to charge at the nearest enemy and try to slay it.
"""
D.moveRight = class MoveRight extends Doc
doc: ->
"""
Moves the #{@thang.spriteName} right by #{@thang.simpleMoveDistance} meters.
"""
example: ->
"""
this.moveRight();
"""
D.moveLeft = class MoveLeft extends Doc
doc: ->
"""
Moves the #{@thang.spriteName} left by #{@thang.simpleMoveDistance} meters.
"""
example: ->
"""
this.moveLeft();
"""
D.moveUp = class MoveUp extends Doc
doc: ->
"""
Moves the #{@thang.spriteName} up by #{@thang.simpleMoveDistance} meters.
"""
example: ->
"""
this.moveUp();
"""
D.moveDown = class MoveDown extends Doc
doc: ->
"""
Moves the #{@thang.spriteName} down by #{@thang.simpleMoveDistance} meters.
"""
example: ->
"""
this.moveDown();
"""
D.say = class Say extends Doc
doc: ->
"""
Makes the #{@thang.spriteName} say the given message. Anything within #{@thang.voiceRange ? 20} meters will hear it.
"""
args: ->
[new Arg "message", "string", "\"Follow me!\"", "The message to say."]
D.chaseAndAttack = class ChaseAndAttack extends Doc
doc: ->
"""
Makes the #{@thang.spriteName} attack `target` if in range, otherwise move to `target`.
"""
args: ->
[new Arg "target", "object", "this.getNearestEnemy()", "The unit to chase and attack."]
D.wait = class Wait extends Doc
doc: ->
"""
The `wait()` method makes the #{@thang.spriteName} wait for a moment before continuing to execute the rest of the code.
It currently doesn't work inside nested functions in a `plan()` method.
"""
args: ->
[
new Arg "duration", "number", "0.1", "Number of seconds to wait."
]
D.addRect = class AddRect extends Doc
doc: ->
"""
The `addRect()` method adds a rectangle centered at the given `(x, y)` coordinate with the given `width` and `height`.
"""
args: ->
[
new Arg "x", "number", "30", "x-coordinate of center of the rectangle."
new Arg "y", "number", "12", "y-coordinate of center of the rectangle."
new Arg "width", "number", "4", "width of the rectangle."
new Arg "height", "number", "24", "height of the rectangle."
]
D.removeRectAt = class RemoveRectAt extends Doc
doc: ->
"""
The `removeRectAt()` method removes a previously added rectangle centered at the given `(x, y)` coordinate.
"""
args: ->
[
new Arg "x", "number", "30", "x-coordinate of center of the rectangle to remove."
new Arg "y", "number", "12", "y-coordinate of center of the rectangle to remove."
]
D.getNavGrid = class GetNavGrid extends Doc
doc: ->
"""
The `getNavGrid()` method returns an undocumented data structure CodeCombat uses in its pathfinding system. Sorry--will improve.
Just use its `grid` property, which is a two-dimensional array with one-meter resolution indicating where the walls are:
```
var grid = this.getNavGrid().grid;
var y = 12;
var x = 30;
var occupied = grid[y][x].length > 0;
```
"""
D.spawnedRectangles = class SpawnedRectangles extends Doc
doc: ->
"""
An array of rectangle objects which have been added with the `addRect()` method.
You can get a rectangle's dimensions, like this:
```
for(var i = 0; i < this.spawnedRectangles.length; ++i) {
var rect = this.spawnedRectangles[i];
// rect.pos.x, rect.pos.y, rect.width, rect.height
}
```
"""
D.pow = class Pow extends Doc
owner: "Math"
doc: ->
"""
Returns `base` to the `exponent` power, that is, <code>base<sup>exponent</sup></code>.
"""
example: ->
"""
Math.pow(7, 2); // returns 49
"""
args: ->
[
new Arg "base", "number", "7", "The base number."
new Arg "exponent", "number", "2", "The exponent used to raise the `base`."
]
D.sqrt = class Sqrt extends Doc
owner: "Math"
doc: ->
"""
Returns the square root of a non-negative number. Equivalent to `Math.pow(x, 0.5)`.
"""
example: ->
"""
Math.sqrt(49); // returns 7
"""
args: ->
[new Arg "x", "number", "49", ""]
D.sin = class Sin extends Doc
owner: "Math"
doc: ->
"""
Returns the sine of a number (between -1 and 1).
"""
example: ->
"""
Math.sin(Math.PI / 4); // returns 2
"""
args: ->
[new Arg "x", "number", "Math.PI / 2", "A number in radians."]
D.cos = class Cos extends Doc
owner: "Math"
doc: ->
"""
Returns the cosine of a number (between -1 and 1).
"""
example: ->
"""
Math.cos(3 * Math.PI / 4); // returns -2
"""
args: ->
[new Arg "x", "number", "Math.PI / 2", "A number in radians."]
D.tan = class Tan extends Doc
owner: "Math"
doc: ->
"""
Returns the tangent of a number (between -1 and 1).
"""
example: ->
"""
Math.tan(Math.PI / 4); // returns 0.9999999999999999
"""
args: ->
[new Arg "x", "number", "Math.PI / 2", "A number in radians."]
D.atan2 = class Atan2 extends Doc
owner: "Math"
doc: ->
"""
Returns the arctangent of the quotient of its arguments--a numeric value between -π and π representing the counterclockwise angle theta of an (x, y) point and the positive X axis.
"""
args: ->
[
new Arg "y", "number", "90", ""
new Arg "x", "number", "15", ""
]
D.PI = class PI extends Doc
owner: "Math"
doc: ->
"""
The ratio of the circumference of a circle to its diameter, approximately 3.14159.
"""
D.random = class Random extends Doc
owner: "Math"
doc: ->
"""
Returns a random number x such that 0 <= x < 1.
"""

View file

@ -78,6 +78,7 @@ module.exports.thangNames = thangNames =
"Giselle"
"Bernadette"
"Hershell"
"Gawain"
]
"Archer F": [
"Phoebe"
@ -107,6 +108,9 @@ module.exports.thangNames = thangNames =
"Archer M": [
"Brian"
"Cole"
"Roman"
"Hunter"
"Simon"
]
"Ogre Munchkin M": [
"Brack"
@ -133,6 +137,8 @@ module.exports.thangNames = thangNames =
"Iyert"
"Palt"
"Shmeal"
"Gurzunn"
"Yugark"
]
"Ogre M": [
"Krogg"
@ -143,11 +149,14 @@ module.exports.thangNames = thangNames =
"Mak Fod"
"Trung"
"Axe Ox"
"Vargutt"
]
"Ogre F": [
"Nareng"
"Morthrug"
"Glonc"
"Marghurk"
]
"Ogre Brawler": [
"Grul'thock"
@ -161,6 +170,7 @@ module.exports.thangNames = thangNames =
"Zeredd"
"Borgag"
"Grognar"
"Ironjaw"
]
"Ogre Fangrider": [
"Dreek"

View file

@ -32,6 +32,9 @@ module.exports.CollisionCategory = class CollisionCategory
# "ground_and_air_<team>" units don't hit ground or air units on their team (so missiles don't hit same team)
sameTeam = @superteamIndex and cat.superteamIndex is @superteamIndex
return false if sameTeam and @ground and @air
# actually, "ground_and_air<team>" units don't hit any ground_and_air units (temp missile collision fix)
return false if @ground and @air and cat.ground and cat.air
# "ground" collides with "ground"
return true if cat.ground and @ground

View file

@ -67,7 +67,7 @@ module.exports = class ThangState
restore: ->
# Restore trackedProperties' values to @thang, retrieving them from @trackedPropertyValues if needed. Optimize it.
return @ if @thang._state is @
return @ if @thang._state is @ and not @thang.partialState
unless @hasRestored # Restoring in a deserialized World for first time
props = []
for prop, propIndex in @trackedPropertyKeys
@ -81,6 +81,26 @@ module.exports = class ThangState
else # Restoring later times
for prop, propIndex in @trackedPropertyKeys
@thang[prop] = @props[propIndex]
@thang.partialState = false
@
restorePartial: (ratio) ->
inverse = 1 - ratio
for prop, propIndex in @trackedPropertyKeys when prop is "pos" or prop is "rotation"
if @hasRestored
value = @props[propIndex]
else
type = @trackedPropertyTypes[propIndex]
storage = @trackedPropertyValues[propIndex]
value = @getStoredProp propIndex, type, storage
if prop is "pos"
@thang.pos = @thang.pos.copy()
@thang.pos.x = inverse * @thang.pos.x + ratio * value.x
@thang.pos.y = inverse * @thang.pos.y + ratio * value.y
@thang.pos.z = inverse * @thang.pos.z + ratio * value.z
else if prop is "rotation"
@thang.rotation = inverse * @thang.rotation + ratio * value
@thang.partialState = true
@
serialize: (frameIndex, trackedPropertyIndices, trackedPropertyTypes, trackedPropertyValues, specialValuesToKeys, specialKeysToValues) ->

View file

@ -2,7 +2,7 @@
class Vector
@className: "Vector"
# Class methods for nondestructively operating
for name in ['add', 'subtract', 'multiply', 'divide']
for name in ['add', 'subtract', 'multiply', 'divide', 'limit', 'normalize']
do (name) ->
Vector[name] = (a, b, useZ) ->
a.copy()[name](b, useZ)

View file

@ -32,12 +32,6 @@ module.exports = class World
@rand = new Rand 0
@frames = [new WorldFrame(@, 0)]
# --- This config needs to move into Systems config --- TODO
playableTeams: ["humans"]
teamForPlayer: (n) ->
@playableTeams[n % @playableTeams.length]
# -----------------------------------------------------
getFrame: (frameIndex) ->
# Optimize it a bit--assume we have all if @ended and are at the previous frame otherwise
frames = @frames
@ -61,7 +55,7 @@ module.exports = class World
@thangMap[thang.id] = thang
thangDialogueSounds: ->
if @frames.length < @totalFrames then worldShouldBeOverBeforeGrabbingDialogue
if @frames.length < @totalFrames then throw new Error("World should be over before grabbing dialogue")
[sounds, seen] = [[], {}]
for frame in @frames
for thangID, state of frame.thangStateMap
@ -78,7 +72,7 @@ module.exports = class World
(@runtimeErrors ?= []).push error
(@unhandledRuntimeErrors ?= []).push error
loadFrames: (loadedCallback, errorCallback, loadProgressCallback) =>
loadFrames: (loadedCallback, errorCallback, loadProgressCallback) ->
return if @aborted
unless @thangs.length
console.log "Warning: loadFrames called on empty World (no thangs)."
@ -251,7 +245,7 @@ module.exports = class World
serialize: ->
# Code hotspot; optimize it
if @frames.length < @totalFrames then worldShouldBeOverBeforeSerialization
if @frames.length < @totalFrames then throw new Error("World Should Be Over Before Serialization")
[transferableObjects, nontransferableObjects] = [0, 0]
o = {name: @name, totalFrames: @totalFrames, maxTotalFrames: @maxTotalFrames, frameRate: @frameRate, dt: @dt, victory: @victory, userCodeMap: {}, trackedProperties: {}}
o.trackedProperties[prop] = @[prop] for prop in @trackedProperties or []
@ -259,7 +253,7 @@ module.exports = class World
for thangID, methods of @userCodeMap
serializedMethods = o.userCodeMap[thangID] = {}
for methodName, method of methods
serializedMethods[methodName] = method.serialize()
serializedMethods[methodName] = method.serialize?() ? method # serialize the method again if it has been deserialized
t0 = now()
o.trackedPropertiesThangIDs = []
@ -426,7 +420,7 @@ module.exports = class World
pos = camera.worldToSurface {x: pos.x, y: pos.y} if camera # without z
if not lastPos.x? or (Math.abs(lastPos.x - pos.x) + Math.abs(lastPos.y - pos.y)) > 1
lastPos = pos
allPoints.push lastPos.y, lastPos.x
allPoints.push lastPos.y, lastPos.x unless lastPos.y is 0 and lastPos.x is 0
allPoints.reverse()
@pointsForThangCache[cacheKey] = allPoints
@ -464,3 +458,7 @@ module.exports = class World
colorConfigs = {}
colorConfigs[teamName] = config.color for teamName, config of teamConfigs
colorConfigs
teamForPlayer: (n) ->
playableTeams = @playableTeams ? ['humans']
playableTeams[n % playableTeams.length]

View file

@ -25,6 +25,9 @@ module.exports = class WorldFrame
#console.log "Frame", @time, "restoring state for", thang.id, "and saying it don't exist"
thang.exists = false
restorePartialState: (ratio) ->
thangState.restorePartial ratio for thangID, thangState of @thangStateMap
restoreStateForThang: (thang) ->
thangState = @thangStateMap[thang.id]
if not thangState

View file

@ -42,9 +42,9 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
# cla_agree: "I AGREE"
# login:
# sign_up: "Create Account"
# log_in: "Log In"
# log_out: "Log Out"
# sign_up: "Create An Account"
# recover: "recover account"
# recover:
@ -104,6 +104,14 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
# wizard_settings:
# title: "Wizard Settings"
# customize_avatar: "Customize Your Avatar"
# clothes: "Clothes"
# trim: "Trim"
# cloud: "Cloud"
# spell: "Spell"
# boots: "Boots"
# hue: "Hue"
# saturation: "Saturation"
# lightness: "Lightness"
# account_settings:
# title: "Account Settings"
@ -150,7 +158,7 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
# gravatar_profile_link: "Full Gravatar Profile"
# play_level:
# level_load_error: "Level could not be loaded."
# level_load_error: "Level could not be loaded: "
# done: "Done"
# grid: "Grid"
# customize_wizard: "Customize Wizard"
@ -173,7 +181,7 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
# victory_go_home: "Go Home"
# victory_review: "Tell us more!"
# victory_hour_of_code_done: "Are You Done?"
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
# multiplayer_title: "Multiplayer Settings"
# multiplayer_link_description: "Give this link to anyone to have them join you."
# multiplayer_hint_label: "Hint:"
@ -183,7 +191,7 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
# tome_minion_spells: "Your Minions' Spells"
# tome_read_only_spells: "Read-Only Spells"
# tome_other_units: "Other Units"
# tome_cast_button_castable: "Cast"
# tome_cast_button_castable: "Cast Spell"
# tome_cast_button_casting: "Casting"
# tome_cast_button_cast: "Spell Cast"
# tome_autocast_delay: "Autocast Delay"
@ -352,6 +360,7 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
# alert_account_message_pref: "To subscribe for class emails, you'll need to "
# alert_account_message_suf: "first."
# alert_account_message_create_url: "create an account"
# archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
# archmage_introduction: "One of the best parts about building games is they synthesize so many different things. Graphics, sound, real-time networking, social networking, and of course many of the more common aspects of programming, from low-level database management, and server administration to user facing design and interface building. There's a lot to do, and if you're an experienced programmer with a hankering to really dive into the nitty-gritty of CodeCombat, this class might be for you. We would love to have your help building the best programming game ever."
# class_attributes: "Class Attributes"
# archmage_attribute_1_pref: "Knowledge in "
@ -364,10 +373,12 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
# join_desc_4: "and we'll go from there!"
# join_url_email: "Email us"
# join_url_hipchat: "public HipChat room"
# more_about_archmage: "Learn More About Becoming A Powerful Archmage"
# more_about_archmage: "Learn More About Becoming an Archmage"
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
# artisan_summary_suf: "then this class is for you."
# artisan_introduction_pref: "We must construct additional levels! People be clamoring for more content, and we can only build so many ourselves. Right now your workstation is level one; our level editor is barely usable even by its creators, so be wary. If you have visions of campaigns spanning for-loops to"
# artisan_introduction_suf: "to then this class might be for you."
# artisan_introduction_suf: "then this class might be for you."
# artisan_attribute_1: "Any experience in building content like this would be nice, such as using Blizzard's level editors. But not required!"
# artisan_attribute_2: "A hankering to do a whole lot of testing and iteration. To make good levels, you need to take it to others and watch them play it, and be prepared to find a lot of things to fix."
# artisan_attribute_3: "For the time being, endurance en par with an Adventurer. Our Level Editor is super preliminary and frustrating to use. You have been warned!"
@ -376,46 +387,52 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
# artisan_join_step2: "Create a new level and explore existing levels."
# artisan_join_step3: "Find us in our public HipChat room for help."
# artisan_join_step4: "Post your levels on the forum for feedback."
# more_about_artisan: "Learn More About Becoming A Creative Artisan"
# more_about_artisan: "Learn More About Becoming an Artisan"
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class is for you."
# adventurer_introduction: "Let's be clear about your role: you are the tank. You're going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class might be for you."
# adventurer_attribute_1: "A thirst for learning. You want to learn how to code and we want to teach you how to code. You'll probably be doing most of the teaching in this case, though."
# adventurer_attribute_2: "Charismatic. Be gentle but articulate about what needs improving, and offer suggestions on how to improve."
# adventurer_join_pref: "Either get together with (or recruit!) an Artisan and work with them, or check the box below to receive emails when there are new levels to test. We'll also be posting about levels to review on our networks like"
# adventurer_forum_url: "our forum"
# adventurer_join_suf: "so if you prefer to be notified those ways, sign up there!"
# more_about_adventurer: "Learn More About Becoming A Brave Adventurer"
# more_about_adventurer: "Learn More About Becoming an Adventurer"
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
# scribe_introduction_pref: "CodeCombat isn't just going to be a bunch of levels. It will also include a resource for knowledge, a wiki of programming concepts that levels can hook into. That way rather than each Artisan having to describe in detail what a comparison operator is, they can simply link their level to the Article describing them that is already written for the player's edification. Something along the lines of what the "
# scribe_introduction_url_mozilla: "Mozilla Developer Network"
# scribe_introduction_suf: " has built. If your idea of fun is articulating the concepts of programming in Markdown form, then this class might be for you."
# scribe_attribute_1: "Skill in words is pretty much all you need. Not only grammar and spelling, but able to convey complicated ideas to others."
# contact_us_url: "Contact us"
# scribe_join_description: "tell us a little about yourself, your experience with programming and what sort of things you'd like to write about. We'll go from there!"
# more_about_scribe: "Learn More About Becoming A Diligent Scribe"
# more_about_scribe: "Learn More About Becoming a Scribe"
# scribe_subscribe_desc: "Get emails about article writing announcements."
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
# diplomat_introduction_pref: "So, if there's one thing we learned from the "
# diplomat_launch_url: "launch in October"
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries, particularly Brazil! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_attribute_1: "Fluency in English and the language you would like to translate to. When conveying complicated ideas, it's important to have a strong grasp in both!"
# diplomat_join_pref: "We've started a lot of initial translations at "
# diplomat_doc_url: "this forum post"
# diplomat_join_suf: "so check it out and add things for your language. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming A Great Diplomat"
# diplomat_join_pref_github: "Find your language locale file "
# diplomat_github_url: "on GitHub"
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming a Diplomat"
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
# ambassador_introduction: "This is a community we're building, and you are the connections. We've got Olark chats, emails, and social networks with lots of people to talk with and help get acquainted with the game and learn from. If you want to help people get involved and have fun, and get a good feel of the pulse of CodeCombat and where we're going, then this class might be for you."
# ambassador_attribute_1: "Communication skills. Be able to identify the problems players are having and help them solve them. Also, keep the rest of us informed about what players are saying, what they like and don't like and want more of!"
# ambassador_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll go from there!"
# ambassador_join_note_strong: "Note"
# ambassador_join_note_desc: "One of our top priorities is to build multiplayer where players having difficulty solving levels can summon higher level wizards to help them. This will be a great way for ambassadors to do their thing. We'll keep you posted!"
# more_about_ambassador: "Learn More About Becoming A Helpful Ambassador"
# more_about_ambassador: "Learn More About Becoming an Ambassador"
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
# counselor_introduction_1: "Do you have life experience? A different perspective on things that can help us decide how to shape CodeCombat? Of all these roles, this will probably take the least time, but individually you may make the most difference. We're on the lookout for wisened sages, particularly in areas like: teaching, game development, open source project management, technical recruiting, entrepreneurship, or design."
# counselor_introduction_2: "Or really anything that is relevant to the development of CodeCombat. If you have knowledge and want to share it to help grow this project, then this class might be for you."
# counselor_attribute_1: "Experience, in any of the areas above or something you think might be helpful."
# counselor_attribute_2: "A little bit of free time!"
# counselor_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll put you in our contact list and be in touch when we could use advice (not too often)."
# more_about_counselor: "Learn More About Becoming A Valuable Counselor"
# more_about_counselor: "Learn More About Becoming a Counselor"
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
# diligent_scribes: "Our Diligent Scribes:"
# powerful_archmages: "Our Powerful Archmages:"

View file

@ -1,29 +1,29 @@
module.exports = nativeDescription: "български език", englishDescription: "Bulgarian", translation:
common:
loading: "Loading..."
# saving: "Saving..."
# sending: "Sending..."
# cancel: "Cancel"
# save: "Save"
loading: "Зареждане..."
saving: "Записване..."
sending: "Изпращане..."
cancel: "Отказ"
save: "Запис"
delay_1_sec: "1 секунда"
delay_3_sec: "3 секунди"
delay_5_sec: "5 секунди"
# manual: "Manual"
# fork: "Fork"
# play: "Play"
# delay_1_sec: "1 second"
# delay_3_sec: "3 seconds"
# delay_5_sec: "5 seconds"
# manual: "Manual"
# modal:
# close: "Close"
# okay: "Okay"
modal:
close: "Затвори"
okay: "Добре"
# not_found:
# page_not_found: "Page not found"
not_found:
page_not_found: "Страницата не е намерена"
# nav:
# play: "Levels"
# editor: "Editor"
# blog: "Blog"
# forum: "Forum"
nav:
play: "Нива"
editor: "Редактор"
blog: "Блог"
forum: "Форум"
# admin: "Admin"
# home: "Home"
# contribute: "Contribute"
@ -41,34 +41,34 @@ module.exports = nativeDescription: "български език", englishDescri
# cla_suffix: "."
# cla_agree: "I AGREE"
# login:
# sign_up: "Create Account"
# log_in: "Log In"
# log_out: "Log Out"
# recover: "recover account"
login:
sign_up: "Създай Профил"
log_in: "Вход"
log_out: "Изход"
recover: "Възстанови акаунт"
# recover:
# recover_account_title: "Recover Account"
# send_password: "Send Recovery Password"
recover:
recover_account_title: "Възстанови Акаунт"
send_password: "Изпрати парола за възстановяване"
# signup:
signup:
# create_account_title: "Create Account to Save Progress"
# description: "It's free. Just need a couple things and you'll be good to go:"
# email_announcements: "Receive announcements by email"
# coppa: "13+ or non-USA "
# coppa_why: "(Why?)"
# creating: "Creating Account..."
# sign_up: "Sign Up"
# log_in: "log in with password"
coppa_why: "(Защо?)"
creating: "Създаване на профил..."
sign_up: "Регистриране"
log_in: "Вход с парола"
# home:
# slogan: "Learn to Code JavaScript by Playing a Game"
# no_ie: "CodeCombat does not run in Internet Explorer 9 or older. Sorry!"
# no_mobile: "CodeCombat wasn't designed for mobile devices and may not work!"
# play: "Play"
home:
slogan: "Научи се да програмираш на JavaScript, докато играеш игра "
no_ie: "CodeCombat не работи под Internet Explorer 9 или по-стар. Съжалявам!"
no_mobile: "CodeCombat не е направен за мобилни устройства и може да не работи!"
play: "Играй"
# play:
# choose_your_level: "Choose Your Level"
play:
choose_your_level: "Избери своето ниво"
# adventurer_prefix: "You can jump to any level below, or discuss the levels on "
# adventurer_forum: "the Adventurer forum"
# adventurer_suffix: "."
@ -104,6 +104,14 @@ module.exports = nativeDescription: "български език", englishDescri
# wizard_settings:
# title: "Wizard Settings"
# customize_avatar: "Customize Your Avatar"
# clothes: "Clothes"
# trim: "Trim"
# cloud: "Cloud"
# spell: "Spell"
# boots: "Boots"
# hue: "Hue"
# saturation: "Saturation"
# lightness: "Lightness"
# account_settings:
# title: "Account Settings"
@ -133,12 +141,12 @@ module.exports = nativeDescription: "български език", englishDescri
# saved: "Changes Saved"
# password_mismatch: "Password does not match."
# account_profile:
# edit_settings: "Edit Settings"
account_profile:
edit_settings: "Промени настройките"
# profile_for_prefix: "Profile for "
# profile_for_suffix: ""
# profile: "Profile"
# user_not_found: "No user found. Check the URL?"
user_not_found: "Няма намерен потребител. Провери URL-а?"
# gravatar_not_found_mine: "We couldn't find your profile associated with:"
# gravatar_not_found_email_suffix: "."
# gravatar_signup_prefix: "Sign up at "
@ -149,9 +157,9 @@ module.exports = nativeDescription: "български език", englishDescri
# gravatar_accounts: "As Seen On"
# gravatar_profile_link: "Full Gravatar Profile"
# play_level:
# level_load_error: "Level could not be loaded."
# done: "Done"
play_level:
level_load_error: "Нивото не може да бъде заредено: "
done: "Готово"
# grid: "Grid"
# customize_wizard: "Customize Wizard"
# home: "Home"
@ -173,7 +181,7 @@ module.exports = nativeDescription: "български език", englishDescri
# victory_go_home: "Go Home"
# victory_review: "Tell us more!"
# victory_hour_of_code_done: "Are You Done?"
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
# multiplayer_title: "Multiplayer Settings"
# multiplayer_link_description: "Give this link to anyone to have them join you."
# multiplayer_hint_label: "Hint:"
@ -183,7 +191,7 @@ module.exports = nativeDescription: "български език", englishDescri
# tome_minion_spells: "Your Minions' Spells"
# tome_read_only_spells: "Read-Only Spells"
# tome_other_units: "Other Units"
# tome_cast_button_castable: "Cast"
# tome_cast_button_castable: "Cast Spell"
# tome_cast_button_casting: "Casting"
# tome_cast_button_cast: "Spell Cast"
# tome_autocast_delay: "Autocast Delay"
@ -239,22 +247,22 @@ module.exports = nativeDescription: "български език", englishDescri
# new_component_title: "Create New Component"
# new_component_field_system: "System"
# article:
# edit_btn_preview: "Preview"
# edit_article_title: "Edit Article"
article:
edit_btn_preview: "Преглед"
edit_article_title: "Промени статията"
# general:
# and: "and"
# name: "Name"
general:
and: "и"
name: "Име"
# body: "Body"
# version: "Version"
version: "Версия"
# commit_msg: "Commit Message"
# version_history_for: "Version History for: "
# results: "Results"
# description: "Description"
# or: "or"
# email: "Email"
# message: "Message"
results: "Резултати"
description: "Описание"
or: "или"
email: "Email"
message: "Съобщение"
# about:
# who_is_codecombat: "Who is CodeCombat?"
@ -352,6 +360,7 @@ module.exports = nativeDescription: "български език", englishDescri
# alert_account_message_pref: "To subscribe for class emails, you'll need to "
# alert_account_message_suf: "first."
# alert_account_message_create_url: "create an account"
# archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
# archmage_introduction: "One of the best parts about building games is they synthesize so many different things. Graphics, sound, real-time networking, social networking, and of course many of the more common aspects of programming, from low-level database management, and server administration to user facing design and interface building. There's a lot to do, and if you're an experienced programmer with a hankering to really dive into the nitty-gritty of CodeCombat, this class might be for you. We would love to have your help building the best programming game ever."
# class_attributes: "Class Attributes"
# archmage_attribute_1_pref: "Knowledge in "
@ -364,10 +373,12 @@ module.exports = nativeDescription: "български език", englishDescri
# join_desc_4: "and we'll go from there!"
# join_url_email: "Email us"
# join_url_hipchat: "public HipChat room"
# more_about_archmage: "Learn More About Becoming A Powerful Archmage"
# more_about_archmage: "Learn More About Becoming an Archmage"
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
# artisan_summary_suf: "then this class is for you."
# artisan_introduction_pref: "We must construct additional levels! People be clamoring for more content, and we can only build so many ourselves. Right now your workstation is level one; our level editor is barely usable even by its creators, so be wary. If you have visions of campaigns spanning for-loops to"
# artisan_introduction_suf: "to then this class might be for you."
# artisan_introduction_suf: "then this class might be for you."
# artisan_attribute_1: "Any experience in building content like this would be nice, such as using Blizzard's level editors. But not required!"
# artisan_attribute_2: "A hankering to do a whole lot of testing and iteration. To make good levels, you need to take it to others and watch them play it, and be prepared to find a lot of things to fix."
# artisan_attribute_3: "For the time being, endurance en par with an Adventurer. Our Level Editor is super preliminary and frustrating to use. You have been warned!"
@ -376,46 +387,52 @@ module.exports = nativeDescription: "български език", englishDescri
# artisan_join_step2: "Create a new level and explore existing levels."
# artisan_join_step3: "Find us in our public HipChat room for help."
# artisan_join_step4: "Post your levels on the forum for feedback."
# more_about_artisan: "Learn More About Becoming A Creative Artisan"
# more_about_artisan: "Learn More About Becoming an Artisan"
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class is for you."
# adventurer_introduction: "Let's be clear about your role: you are the tank. You're going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class might be for you."
# adventurer_attribute_1: "A thirst for learning. You want to learn how to code and we want to teach you how to code. You'll probably be doing most of the teaching in this case, though."
# adventurer_attribute_2: "Charismatic. Be gentle but articulate about what needs improving, and offer suggestions on how to improve."
# adventurer_join_pref: "Either get together with (or recruit!) an Artisan and work with them, or check the box below to receive emails when there are new levels to test. We'll also be posting about levels to review on our networks like"
# adventurer_forum_url: "our forum"
# adventurer_join_suf: "so if you prefer to be notified those ways, sign up there!"
# more_about_adventurer: "Learn More About Becoming A Brave Adventurer"
# more_about_adventurer: "Learn More About Becoming an Adventurer"
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
# scribe_introduction_pref: "CodeCombat isn't just going to be a bunch of levels. It will also include a resource for knowledge, a wiki of programming concepts that levels can hook into. That way rather than each Artisan having to describe in detail what a comparison operator is, they can simply link their level to the Article describing them that is already written for the player's edification. Something along the lines of what the "
# scribe_introduction_url_mozilla: "Mozilla Developer Network"
# scribe_introduction_suf: " has built. If your idea of fun is articulating the concepts of programming in Markdown form, then this class might be for you."
# scribe_attribute_1: "Skill in words is pretty much all you need. Not only grammar and spelling, but able to convey complicated ideas to others."
# contact_us_url: "Contact us"
# scribe_join_description: "tell us a little about yourself, your experience with programming and what sort of things you'd like to write about. We'll go from there!"
# more_about_scribe: "Learn More About Becoming A Diligent Scribe"
# more_about_scribe: "Learn More About Becoming a Scribe"
# scribe_subscribe_desc: "Get emails about article writing announcements."
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
# diplomat_introduction_pref: "So, if there's one thing we learned from the "
# diplomat_launch_url: "launch in October"
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries, particularly Brazil! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_attribute_1: "Fluency in English and the language you would like to translate to. When conveying complicated ideas, it's important to have a strong grasp in both!"
# diplomat_join_pref: "We've started a lot of initial translations at "
# diplomat_doc_url: "this forum post"
# diplomat_join_suf: "so check it out and add things for your language. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming A Great Diplomat"
# diplomat_join_pref_github: "Find your language locale file "
# diplomat_github_url: "on GitHub"
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming a Diplomat"
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
# ambassador_introduction: "This is a community we're building, and you are the connections. We've got Olark chats, emails, and social networks with lots of people to talk with and help get acquainted with the game and learn from. If you want to help people get involved and have fun, and get a good feel of the pulse of CodeCombat and where we're going, then this class might be for you."
# ambassador_attribute_1: "Communication skills. Be able to identify the problems players are having and help them solve them. Also, keep the rest of us informed about what players are saying, what they like and don't like and want more of!"
# ambassador_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll go from there!"
# ambassador_join_note_strong: "Note"
# ambassador_join_note_desc: "One of our top priorities is to build multiplayer where players having difficulty solving levels can summon higher level wizards to help them. This will be a great way for ambassadors to do their thing. We'll keep you posted!"
# more_about_ambassador: "Learn More About Becoming A Helpful Ambassador"
# more_about_ambassador: "Learn More About Becoming an Ambassador"
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
# counselor_introduction_1: "Do you have life experience? A different perspective on things that can help us decide how to shape CodeCombat? Of all these roles, this will probably take the least time, but individually you may make the most difference. We're on the lookout for wisened sages, particularly in areas like: teaching, game development, open source project management, technical recruiting, entrepreneurship, or design."
# counselor_introduction_2: "Or really anything that is relevant to the development of CodeCombat. If you have knowledge and want to share it to help grow this project, then this class might be for you."
# counselor_attribute_1: "Experience, in any of the areas above or something you think might be helpful."
# counselor_attribute_2: "A little bit of free time!"
# counselor_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll put you in our contact list and be in touch when we could use advice (not too often)."
# more_about_counselor: "Learn More About Becoming A Valuable Counselor"
# more_about_counselor: "Learn More About Becoming a Counselor"
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
# diligent_scribes: "Our Diligent Scribes:"
# powerful_archmages: "Our Powerful Archmages:"

View file

@ -104,6 +104,14 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
wizard_settings:
title: "Nastavení Kouzelníka"
customize_avatar: "Upravte vás Avatar"
# clothes: "Clothes"
# trim: "Trim"
# cloud: "Cloud"
# spell: "Spell"
# boots: "Boots"
# hue: "Hue"
# saturation: "Saturation"
# lightness: "Lightness"
account_settings:
title: "Nastavení účtu"
@ -136,7 +144,7 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
account_profile:
edit_settings: "Editovat Nastavení"
profile_for_prefix: "Profil pro "
profile_for_suffix: ""
# profile_for_suffix: ""
profile: "Profil"
user_not_found: "Uživatel nenalezen. Zkontrolujte adresu URL?"
gravatar_not_found_mine: "Nenalezli jsme profil asociovaný s:"
@ -150,7 +158,7 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
gravatar_profile_link: "Účet Gravatar"
play_level:
level_load_error: "Úroveň se nepodařilo otevřít."
level_load_error: "Úroveň se nepodařilo otevřít: "
done: "Hotovo"
grid: "Mřížka"
customize_wizard: "Upravit Kouzelníka"
@ -164,7 +172,7 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
reload_title: "Znovunačíst veškerý kód?"
reload_really: "Opravdu chcete resetovat tuto úroveň do počátečního stavu?"
reload_confirm: "Znovu načíst vše"
victory_title_prefix: ""
# victory_title_prefix: ""
victory_title_suffix: " Hotovo"
victory_sign_up: "Přihlásit se pro uložení postupu"
victory_sign_up_poke: "Chcete uložit váš kód? Vytvořte si účet zdarma!"
@ -238,6 +246,7 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
create_system_title: "Vytvořit nový systém"
new_component_title: "Vytvořit novou komponentu"
new_component_field_system: "Systém"
article:
edit_btn_preview: "Náhled"
edit_article_title: "Editovat článek"
@ -351,6 +360,7 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
alert_account_message_pref: "K přihlášení odebírání emailů si nejprve musíte "
alert_account_message_suf: "vytvořit účet"
alert_account_message_create_url: "."
# archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
archmage_introduction: "Jedna z nejlepších věcí na vytváření her je to, že se jedná o spojení různých procesů. Grafika, zvuk, síťování v reálném čase, mezilidské vztahy a samozřejmě také spousta běžných aspektů programování, od nízkoúrovňového managementu databáze přes administraci serverů až po tvorbu uživatelská rozhraní. Je zde spousta práce a pokud jste zkušený programátor a všeuměl připravený k ponoření se do hloubek CodeCombatu, tato skupina je pro vás. Budeme moc rádi za vaši pomoc při tvorbě té nejlepší programovací hry."
class_attributes: "Vlastnosti"
archmage_attribute_1_pref: "Znáte "
@ -365,6 +375,8 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
join_url_hipchat: "veřejné HipChat chatovací místnosti"
more_about_archmage: "Dozvědět se více o tom, jak se stát mocným Arcimágem"
archmage_subscribe_desc: "Dostávat emailem oznámení a informacemi nových programovacích příležitostech"
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
# artisan_summary_suf: "then this class is for you."
artisan_introduction_pref: "Musíme vytvářet další úrovně! Lidé nás prosí o další obsah, ale sami zvládáme vytvořit jen málo. Naším prvním pracovním zastavením je první úroveň. Editor úrovní je tak-tak použitelný i pro jeho vlastní tvůrce. Máte-li vizi pro vytvoření vnořených úrovní alá "
artisan_introduction_suf: "pak neváhejte, toto je vaše destinace."
artisan_attribute_1: "Předchozí zkušenosti s vytvářením podobného obsahu by byly vítány, například z editorů úrovní Blizzardu, ale nejsou vyžadovány!"
@ -377,6 +389,7 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
artisan_join_step4: "Zveřejněte vaši úroveň na fóru pro připomínkování."
more_about_artisan: "Dozvědět se více o tom, jak se stát kreativním Řemeslníkem"
artisan_subscribe_desc: "Dostávat emailem oznámení a informace o aktualizacích editoru úrovní."
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class is for you."
adventurer_introduction: "Ujasněme si dopředu jednu věc o vaší roli: budete jako tank. Projdete ohněm. Potřebujeme někoho, kdo odzkouší zbrusu nové úrovně a pomůže identifikovat kde je možno je zlepšit. Ten boj bude ohromný - tvorba her je dlouhý proces, který nikdo nezvládne na první pokus. Máte-li na to a vydržíte-li to, pak toto je vaše skupina."
adventurer_attribute_1: "Touha po učení se. Vy se chcete naučit programovat a my vás to chceme naučit. Jenom, v tomto případě to budete vy, kdo bude vyučovat."
adventurer_attribute_2: "Charismatický. Buďte mírný a pečlivě artikulujte co a jak je potřeba zlepšit."
@ -384,7 +397,9 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
adventurer_forum_url: " našem fóru"
adventurer_join_suf: "takže pokud chcete být v obraze, připojte se k nám!"
more_about_adventurer: "Dozvědět se více o tom, jak se stát statečným Dobrodruhem"
adventurer_subscribe_desc: "Dostávat emailem oznámení a informace nových úrovních k testování."
adventurer_subscribe_desc: "Dostávat emailem oznámení a informace nových úrovních k testování."
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
scribe_introduction_pref: "CodeCombat nebude pouze kupa úrovní. Bude také zahrnovat informační zdroje a wiki programovacích konceptů na které se úrovně mohou navázat. Takto, namísto toho aby každý Řemeslník musel sám do detailu popsatco který operátor dělá, mohou jednoduše nalinkovat svoji úroveň na článek existující k edukaci hráčů. Něco ve stylu "
scribe_introduction_url_mozilla: "Mozilla Developer Network"
scribe_introduction_suf: ". Jestliže vás baví popisovat a předávat koncept programování v Markdown editoru, pak tato role může být právě pro vás."
@ -393,15 +408,17 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
scribe_join_description: "dejte nám o vás vědět, o vašich zkušenostech s programováním a o čm byste rádi psali. Od toho začneme!"
more_about_scribe: "Dozvědět se více o tom, jak se stát pilným Pisálkem"
scribe_subscribe_desc: "Dostávat emailem oznámení a informace o článcích."
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
diplomat_introduction_pref: "Jedna z věcí, kterou jsme zjistili během "
diplomat_launch_url: "zahájení v Říjnu"
diplomat_introduction_suf: "bylo, že o CodeCombat je velký zájem i v jiných zemích, obzvláště v Brazílii! Chystáme regiment překladatelů ke zpřístupnění CodeCombatu světu. Pokud chcete nakouknout pod pokličku, dozvědět se o připravovaných novinkách a zpřístupnit úrovně vašim národním kolegům, toto je role pro vás."
diplomat_attribute_1: "Plynulost v angličtině a v jazyce do kterého budete překládat. Při předávání komplexních myšlenek je důležité si být jistí v kramflecích v obou jazycích!"
diplomat_join_pref: "Úvodní překladatelský počin začal v tomto "
diplomat_doc_url: "příspěvku na fóru"
diplomat_join_suf: ", tak si jej přečtěte a případně doplňte informace o vašem překladu. Přihlaste se také k odběru informací o vývoji v internacionalizaci!"
# diplomat_join_pref_github: "Find your language locale file "
# diplomat_github_url: "on GitHub"
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
more_about_diplomat: "Dozvědět se více o tom, jak se stát Diplomatem"
diplomat_subscribe_desc: "Dostávat emailem oznámení a informace o internacionalizaci a o úrovních k překladu."
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
ambassador_introduction: "Zde se tvoří komunita a vy jste její spojení. Využíváme chat, emaily a sociální sítě se spoustou lidí k informování a diskuzím a seznámení s naší hrou. Chcete-li pomoci lidem se přidat a pobavit se a získat dobrý náhled na CodeCombat a kam směřujeme, pak toto je vaše role."
ambassador_attribute_1: "Komunikační schopnosti. Schopnost identifikovat problémy hráčů a pomoci jim je řešit. Naslouchat co hráči říkají, co mají rádi a co rádi nemají a komunikovat to zpět ostatním!"
ambassador_join_desc: "dejte nám o sobě vědět, o tom co děláte a co byste rádi dělali. Od toho začneme!"
@ -409,6 +426,7 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
ambassador_join_note_desc: "Jedna z našich priorit je vytvoření vícehráčové hry, kde hráč, který má problém s řešením úrovní může oslovit a požádat o pomoc zkušenější kouzelníky. To je přesně ten případ a místo pro pomoc Velvyslance . Dáme vám vědět více!"
more_about_ambassador: "Dozvědět se více o tom, jak se stát nápomocným Velvyslancem"
ambassador_subscribe_desc: "Dostávat emailem oznámení a informace o vývoji v podpoře a vícehráčové hře."
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
counselor_introduction_1: "Máte životní zkušenosti? Máte odlišný náhled na věci a jste schopni nám tímto pomoci v dalším vývoji CodeCombatu? Jedna z důležitých rolí i když asi nejméně časově náročná, nicméně každá individualita je schopná udělat velký rozdíl. Hledáme zkušené odborníky, zvláště pak v oblastech vzdělávání, vývoji her managementu open source, source project management, náboru lidských zdrojů, podnikání nebo designu."
counselor_introduction_2: "Nebo cokoliv, co je relevantní ve vývoji CodeCombatu. Máte-li znalosti a jste-li ochotni se o ně podělit pro další růst tohoto projektu , pak toto je role pro vás."
counselor_attribute_1: "Zkušenosti ve výše zmíněných oblastech, nebo něco, čím byste mohli být nápomocni."

View file

@ -104,6 +104,14 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
wizard_settings:
title: "Troldmandsinstillinger"
customize_avatar: "Tilpas din avatar"
# clothes: "Clothes"
# trim: "Trim"
# cloud: "Cloud"
# spell: "Spell"
# boots: "Boots"
# hue: "Hue"
# saturation: "Saturation"
# lightness: "Lightness"
account_settings:
title: "Kontoindstillinger"
@ -136,7 +144,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
account_profile:
edit_settings: "Redigér Indstillinger"
profile_for_prefix: "Profil for "
profile_for_suffix: ""
# profile_for_suffix: ""
profile: "Profil"
user_not_found: "Ingen bruger fundet. Tjek URL'en?"
gravatar_not_found_mine: "Vi kunne ikke finde din profil associeret med:"
@ -150,7 +158,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
gravatar_profile_link: "Fuld Gravatar Profil"
play_level:
level_load_error: "Banen kunne ikke indlæses."
level_load_error: "Banen kunne ikke indlæses: "
done: "Færdig"
grid: "Gitter"
customize_wizard: "Tilpas troldmand"
@ -183,7 +191,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
# tome_minion_spells: "Your Minions' Spells"
# tome_read_only_spells: "Read-Only Spells"
tome_other_units: "Andre enheder"
# tome_cast_button_castable: "Cast"
# tome_cast_button_castable: "Cast Spell"
# tome_cast_button_casting: "Casting"
# tome_cast_button_cast: "Spell Cast"
# tome_autocast_delay: "Autocast Delay"
@ -252,9 +260,9 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
version_history_for: "versionhistorie for: "
results: "resultater"
description: "beskrivelse"
or: "eller"
email: "e-mail"
message: "Besked"
or: "eller"
about:
who_is_codecombat: "Hvem er CodeCombat?"
@ -282,7 +290,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
# page_title: "Legal"
# opensource_intro: "CodeCombat is free to play and completely open source."
# opensource_description_prefix: "Check out "
github_url: "vores GitHub"
# github_url: "our GitHub"
# opensource_description_center: "and help out if you like! CodeCombat is built on dozens of open source projects, and we love them. See "
# archmage_wiki_url: "our Archmage wiki"
# opensource_description_suffix: "for a list of the software that makes this game possible."
@ -290,11 +298,11 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
# practices_description: "These are our promises to you, the player, in slightly less legalese."
# privacy_title: "Privacy"
# privacy_description: "We will not sell any of your personal information. We intend to make money through recruitment eventually, but rest assured we will not distribute your personal information to interested companies without your explicit consent."
security_title: "Sikkerhed"
# security_title: "Security"
# security_description: "We strive to keep your personal information safe. As an open source project, our site is freely open to anyone to review and improve our security systems."
email_title: "E-mail"
# email_title: "Email"
# email_description_prefix: "We will not inundate you with spam. Through"
email_settings_url: "dine e-mail instillinger"
# email_settings_url: "your email settings"
# email_description_suffix: "or through links in the emails we send, you can change your preferences and easily unsubscribe at any time."
# cost_title: "Cost"
# cost_description: "Currently, CodeCombat is 100% free! One of our main goals is to keep it that way, so that as many people can play as possible, regardless of place in life. If the sky darkens, we might have to charge subscriptions or for some content, but we'd rather not. With any luck, we'll be able to sustain the company with:"
@ -317,8 +325,8 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
# art_description_prefix: "All common content is available under the"
# cc_license_url: "Creative Commons Attribution 4.0 International License"
# art_description_suffix: "Common content is anything made generally available by CodeCombat for the purpose of creating Levels. This includes:"
art_music: "Musik"
art_sound: "Lyd"
# art_music: "Music"
# art_sound: "Sound"
# art_artwork: "Artwork"
# art_sprites: "Sprites"
# art_other: "Any and all other non-code creative works that are made available when creating Levels."
@ -335,7 +343,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
# rights_writings: "Writings"
# rights_media: "Media (sounds, music) and any other creative content made specifically for that Level and not made generally available when creating Levels."
# rights_clarification: "To clarify, anything that is made available in the Level Editor for the purpose of making levels is under CC, whereas the content created with the Level Editor or uploaded in the course of creation of Levels is not."
nutshell_title: "I en nødeskal"
# nutshell_title: "In a Nutshell"
# nutshell_description: "Any resources we provide in the Level Editor are free to use as you like for creating Levels. But we reserve the right to restrict distribution of the Levels themselves (that are created on codecombat.com) so that they may be charged for in the future, if that's what ends up happening."
# canonical: "The English version of this document is the definitive, canonical version. If there are any discrepencies between translations, the English document takes precedence."
@ -352,6 +360,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
# alert_account_message_pref: "To subscribe for class emails, you'll need to "
# alert_account_message_suf: "first."
# alert_account_message_create_url: "create an account"
# archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
# archmage_introduction: "One of the best parts about building games is they synthesize so many different things. Graphics, sound, real-time networking, social networking, and of course many of the more common aspects of programming, from low-level database management, and server administration to user facing design and interface building. There's a lot to do, and if you're an experienced programmer with a hankering to really dive into the nitty-gritty of CodeCombat, this class might be for you. We would love to have your help building the best programming game ever."
# class_attributes: "Class Attributes"
# archmage_attribute_1_pref: "Knowledge in "
@ -364,10 +373,12 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
# join_desc_4: "and we'll go from there!"
join_url_email: "Skriv til os"
# join_url_hipchat: "public HipChat room"
# more_about_archmage: "Learn More About Becoming A Powerful Archmage"
# more_about_archmage: "Learn More About Becoming an Archmage"
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
# artisan_summary_suf: "then this class is for you."
# artisan_introduction_pref: "We must construct additional levels! People be clamoring for more content, and we can only build so many ourselves. Right now your workstation is level one; our level editor is barely usable even by its creators, so be wary. If you have visions of campaigns spanning for-loops to"
# artisan_introduction_suf: "to then this class might be for you."
# artisan_introduction_suf: "then this class might be for you."
# artisan_attribute_1: "Any experience in building content like this would be nice, such as using Blizzard's level editors. But not required!"
# artisan_attribute_2: "A hankering to do a whole lot of testing and iteration. To make good levels, you need to take it to others and watch them play it, and be prepared to find a lot of things to fix."
# artisan_attribute_3: "For the time being, endurance en par with an Adventurer. Our Level Editor is super preliminary and frustrating to use. You have been warned!"
@ -376,46 +387,52 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
artisan_join_step2: "Lav en ny bane og udforsk eksisterende baner."
# artisan_join_step3: "Find us in our public HipChat room for help."
# artisan_join_step4: "Post your levels on the forum for feedback."
# more_about_artisan: "Learn More About Becoming A Creative Artisan"
# more_about_artisan: "Learn More About Becoming an Artisan"
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class is for you."
# adventurer_introduction: "Let's be clear about your role: you are the tank. You're going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class might be for you."
# adventurer_attribute_1: "A thirst for learning. You want to learn how to code and we want to teach you how to code. You'll probably be doing most of the teaching in this case, though."
# adventurer_attribute_2: "Charismatic. Be gentle but articulate about what needs improving, and offer suggestions on how to improve."
# adventurer_join_pref: "Either get together with (or recruit!) an Artisan and work with them, or check the box below to receive emails when there are new levels to test. We'll also be posting about levels to review on our networks like"
# adventurer_forum_url: "our forum"
# adventurer_join_suf: "so if you prefer to be notified those ways, sign up there!"
# more_about_adventurer: "Learn More About Becoming A Brave Adventurer"
# more_about_adventurer: "Learn More About Becoming an Adventurer"
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
# scribe_introduction_pref: "CodeCombat isn't just going to be a bunch of levels. It will also include a resource for knowledge, a wiki of programming concepts that levels can hook into. That way rather than each Artisan having to describe in detail what a comparison operator is, they can simply link their level to the Article describing them that is already written for the player's edification. Something along the lines of what the "
# scribe_introduction_url_mozilla: "Mozilla Developer Network"
# scribe_introduction_suf: " has built. If your idea of fun is articulating the concepts of programming in Markdown form, then this class might be for you."
# scribe_attribute_1: "Skill in words is pretty much all you need. Not only grammar and spelling, but able to convey complicated ideas to others."
# contact_us_url: "Contact us"
# scribe_join_description: "tell us a little about yourself, your experience with programming and what sort of things you'd like to write about. We'll go from there!"
# more_about_scribe: "Learn More About Becoming A Diligent Scribe"
# more_about_scribe: "Learn More About Becoming a Scribe"
# scribe_subscribe_desc: "Get emails about article writing announcements."
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
# diplomat_introduction_pref: "So, if there's one thing we learned from the "
# diplomat_launch_url: "launch in October"
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries, particularly Brazil! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_attribute_1: "Fluency in English and the language you would like to translate to. When conveying complicated ideas, it's important to have a strong grasp in both!"
# diplomat_join_pref: "We've started a lot of initial translations at "
# diplomat_doc_url: "this forum post"
# diplomat_join_suf: "so check it out and add things for your language. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming A Great Diplomat"
# diplomat_join_pref_github: "Find your language locale file "
# diplomat_github_url: "on GitHub"
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming a Diplomat"
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
# ambassador_introduction: "This is a community we're building, and you are the connections. We've got Olark chats, emails, and social networks with lots of people to talk with and help get acquainted with the game and learn from. If you want to help people get involved and have fun, and get a good feel of the pulse of CodeCombat and where we're going, then this class might be for you."
# ambassador_attribute_1: "Communication skills. Be able to identify the problems players are having and help them solve them. Also, keep the rest of us informed about what players are saying, what they like and don't like and want more of!"
# ambassador_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll go from there!"
# ambassador_join_note_strong: "Note"
# ambassador_join_note_desc: "One of our top priorities is to build multiplayer where players having difficulty solving levels can summon higher level wizards to help them. This will be a great way for ambassadors to do their thing. We'll keep you posted!"
# more_about_ambassador: "Learn More About Becoming A Helpful Ambassador"
# more_about_ambassador: "Learn More About Becoming an Ambassador"
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
# counselor_introduction_1: "Do you have life experience? A different perspective on things that can help us decide how to shape CodeCombat? Of all these roles, this will probably take the least time, but individually you may make the most difference. We're on the lookout for wisened sages, particularly in areas like: teaching, game development, open source project management, technical recruiting, entrepreneurship, or design."
# counselor_introduction_2: "Or really anything that is relevant to the development of CodeCombat. If you have knowledge and want to share it to help grow this project, then this class might be for you."
# counselor_attribute_1: "Experience, in any of the areas above or something you think might be helpful."
# counselor_attribute_2: "A little bit of free time!"
# counselor_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll put you in our contact list and be in touch when we could use advice (not too often)."
# more_about_counselor: "Learn More About Becoming A Valuable Counselor"
# more_about_counselor: "Learn More About Becoming a Counselor"
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
# diligent_scribes: "Our Diligent Scribes:"
# powerful_archmages: "Our Powerful Archmages:"

View file

@ -2,7 +2,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
common:
loading: "Lade..."
saving: "Speichere..."
sending: "Übertrage..." # or Sende... ?
sending: "Übertrage..."
cancel: "Abbrechen"
save: "Speichern"
delay_1_sec: "1 Sekunde"
@ -36,10 +36,10 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
versions:
save_version_title: "Neue Version speichern"
new_major_version: "Neue Hauptversion"
cla_prefix: "Damit Änderungen gespeichert werden können, musst du unsere Lizenzbedingungen (" # To save changes, first you must agree to our ...
cla_url: "CLA" # ? CLA: What is this? -> CodeCombat Individual Contributor License Agreement
cla_prefix: "Damit Änderungen gespeichert werden können, musst du unsere Lizenzbedingungen ("
cla_url: "CLA"
cla_suffix: ") akzeptieren."
cla_agree: "Ich stimme zu" # die Bestimmungen / I agree the rules
cla_agree: "Ich stimme zu"
login:
sign_up: "Registrieren"
@ -104,6 +104,14 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
wizard_settings:
title: "Zauberer Einstellungen"
customize_avatar: "Individualisiere deinen Avatar"
# clothes: "Clothes"
# trim: "Trim"
# cloud: "Cloud"
# spell: "Spell"
# boots: "Boots"
# hue: "Hue"
# saturation: "Saturation"
# lightness: "Lightness"
account_settings:
title: "Accounteinstellungen"
@ -122,6 +130,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
new_password_verify: "Passwort verifizieren"
email_subscriptions: "Email Abonnements"
email_announcements: "Ankündigungen"
# email_notifications_description: "Get periodic notifications for your account."
email_announcements_description: "Erhalte regelmäßig Mitteilungen für deinen Account."
contributor_emails: "Unterstützer Email"
contribute_prefix: "Wir suchen nach Leuten, die mitmachen! Schau dir die"
@ -139,7 +148,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
profile: "Profil"
user_not_found: "Kein Nutzer gefunden. URL überprüft?"
gravatar_not_found_mine: "Wir konnten dein Profil nicht finden, das mit folgender Email Adresse verbunden ist:"
# gravatar_not_found_email_suffix: "."
gravatar_not_found_email_suffix: "."
gravatar_signup_prefix: "Melde dich an unter "
gravatar_signup_suffix: " um los zu legen!"
gravatar_not_found_other: "Leider ist kein Profil mit der Email Adresse verknüpft."
@ -149,7 +158,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
gravatar_profile_link: "Gravatar Profil"
play_level:
level_load_error: "Level konnte nicht geladen werden."
level_load_error: "Level konnte nicht geladen werden: "
done: "Fertig"
grid: "Raster"
customize_wizard: "Bearbeite den Zauberer"
@ -212,12 +221,11 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
level_title: "Level Editor"
level_description: "Beinhaltet die Werkzeuge zum Scripten, Hochladen von Tönen und zur Konstruktion eigener Logik, damit jedes erdenkliches Level erstellt werden kann. Genau die Sachen, die wir selber benutzen!"
security_notice: "Viele Hauptfunktionen der Editoren sind standardmäßig noch nicht aktiviert. Sobald die Sicherheit dieser Systeme gewährleistet ist, werden sie generell freigeschaltet. Falls Du diese Funktionen früher nutzen möchtest, "
contact_us: "setze dich mit uns in Verbindung!" # kontaktiere uns!
contact_us: "setze dich mit uns in Verbindung!"
hipchat_prefix: "Besuche uns auch in unserem"
hipchat_url: "HipChat room."
level_some_options: "Einige Einstellungsmöglichkeiten?"
# level_tab_thangs: "Thangs" # Things? # <= no Thangs are the components of the level. Check the editor if you're not sure what it is.
# rather dont't translate it
level_tab_thangs: "Thangs"
level_tab_scripts: "Skripte"
level_tab_settings: "Einstellungen"
level_tab_components: "Komponenten"
@ -252,15 +260,15 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
version_history_for: "Versionsgeschichte für: "
results: "Ergebnisse"
description: "Beschreibung"
or: "oder"
email: "Email"
message: "Nachricht"
or: "oder"
about:
who_is_codecombat: "Wer ist CodeCombat?" # Wer steckt hinter CodeCombat # behind
who_is_codecombat: "Wer ist CodeCombat?"
why_codecombat: "Warum CodeCombat?"
who_description_prefix: "gründeten CodeCombat im Jahre 2013 zusammen. Wir entwickelten außerdem "
who_description_suffix: ", die meist benutzte (#1) Web and iOS Applikation 2008 zum Lernen des Schreibens von chinesischen und japanischen Schriftzeichen." # need improvements
who_description_suffix: ", die meist benutzte (#1) Web and iOS Applikation 2008 zum Lernen des Schreibens von chinesischen und japanischen Schriftzeichen."
who_description_ending: "Nun ist es an der Zeit, den Leuten das Programmieren beizubringen."
why_paragraph_1: "Als er Skritter machte, wusste George nicht wie man programmiert und war permanent darüber frustriert, dass er seine Ideen nicht umsetzen konnte. Danach versuchte er es zu lernen, aber das ging ihm zu langsam. Sein Mitbewohner versuchte Codecademy, als er sich umorientierte und aufhörte zu lehren, aber \"langweilte sich\". Jede Woche begann ein neuer Freund mit Codecademy und ließ es dann wieder bleiben. Wir erkannten, dass es das gleiche Problem war, welches wir mit Skritter gelöst hatten: Leute lernen eine Fähigkeit mittels langsamer, intersiver Lerneinheiten, wobei sie schnelle, umfassende Übung bräuchten. Wir kennen Abhilfe."
why_paragraph_2: "Programmieren lernen? Du brauchst keine Stunden. Du musst einen Haufen Code schreiben und dabei Spaß haben."
@ -352,6 +360,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
# alert_account_message_pref: "To subscribe for class emails, you'll need to "
# alert_account_message_suf: "first."
# alert_account_message_create_url: "create an account"
# archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
# archmage_introduction: "One of the best parts about building games is they synthesize so many different things. Graphics, sound, real-time networking, social networking, and of course many of the more common aspects of programming, from low-level database management, and server administration to user facing design and interface building. There's a lot to do, and if you're an experienced programmer with a hankering to really dive into the nitty-gritty of CodeCombat, this class might be for you. We would love to have your help building the best programming game ever."
# class_attributes: "Class Attributes"
# archmage_attribute_1_pref: "Knowledge in "
@ -364,10 +373,12 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
# join_desc_4: "and we'll go from there!"
# join_url_email: "Email us"
# join_url_hipchat: "public HipChat room"
# more_about_archmage: "Learn More About Becoming A Powerful Archmage"
# more_about_archmage: "Learn More About Becoming an Archmage"
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
# artisan_summary_suf: "then this class is for you."
# artisan_introduction_pref: "We must construct additional levels! People be clamoring for more content, and we can only build so many ourselves. Right now your workstation is level one; our level editor is barely usable even by its creators, so be wary. If you have visions of campaigns spanning for-loops to"
# artisan_introduction_suf: "to then this class might be for you."
# artisan_introduction_suf: "then this class might be for you."
# artisan_attribute_1: "Any experience in building content like this would be nice, such as using Blizzard's level editors. But not required!"
# artisan_attribute_2: "A hankering to do a whole lot of testing and iteration. To make good levels, you need to take it to others and watch them play it, and be prepared to find a lot of things to fix."
# artisan_attribute_3: "For the time being, endurance en par with an Adventurer. Our Level Editor is super preliminary and frustrating to use. You have been warned!"
@ -376,46 +387,52 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
# artisan_join_step2: "Create a new level and explore existing levels."
# artisan_join_step3: "Find us in our public HipChat room for help."
# artisan_join_step4: "Post your levels on the forum for feedback."
# more_about_artisan: "Learn More About Becoming A Creative Artisan"
# more_about_artisan: "Learn More About Becoming an Artisan"
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class is for you."
# adventurer_introduction: "Let's be clear about your role: you are the tank. You're going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class might be for you."
# adventurer_attribute_1: "A thirst for learning. You want to learn how to code and we want to teach you how to code. You'll probably be doing most of the teaching in this case, though."
# adventurer_attribute_2: "Charismatic. Be gentle but articulate about what needs improving, and offer suggestions on how to improve."
# adventurer_join_pref: "Either get together with (or recruit!) an Artisan and work with them, or check the box below to receive emails when there are new levels to test. We'll also be posting about levels to review on our networks like"
# adventurer_forum_url: "our forum"
# adventurer_join_suf: "so if you prefer to be notified those ways, sign up there!"
# more_about_adventurer: "Learn More About Becoming A Brave Adventurer"
# more_about_adventurer: "Learn More About Becoming an Adventurer"
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
# scribe_introduction_pref: "CodeCombat isn't just going to be a bunch of levels. It will also include a resource for knowledge, a wiki of programming concepts that levels can hook into. That way rather than each Artisan having to describe in detail what a comparison operator is, they can simply link their level to the Article describing them that is already written for the player's edification. Something along the lines of what the "
# scribe_introduction_url_mozilla: "Mozilla Developer Network"
# scribe_introduction_suf: " has built. If your idea of fun is articulating the concepts of programming in Markdown form, then this class might be for you."
# scribe_attribute_1: "Skill in words is pretty much all you need. Not only grammar and spelling, but able to convey complicated ideas to others."
# contact_us_url: "Contact us"
# scribe_join_description: "tell us a little about yourself, your experience with programming and what sort of things you'd like to write about. We'll go from there!"
# more_about_scribe: "Learn More About Becoming A Diligent Scribe"
# more_about_scribe: "Learn More About Becoming a Scribe"
# scribe_subscribe_desc: "Get emails about article writing announcements."
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
# diplomat_introduction_pref: "So, if there's one thing we learned from the "
# diplomat_launch_url: "launch in October"
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries, particularly Brazil! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_attribute_1: "Fluency in English and the language you would like to translate to. When conveying complicated ideas, it's important to have a strong grasp in both!"
# diplomat_join_pref: "We've started a lot of initial translations at "
# diplomat_doc_url: "this forum post"
# diplomat_join_suf: "so check it out and add things for your language. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming A Great Diplomat"
# diplomat_join_pref_github: "Find your language locale file "
# diplomat_github_url: "on GitHub"
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming a Diplomat"
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
# ambassador_introduction: "This is a community we're building, and you are the connections. We've got Olark chats, emails, and social networks with lots of people to talk with and help get acquainted with the game and learn from. If you want to help people get involved and have fun, and get a good feel of the pulse of CodeCombat and where we're going, then this class might be for you."
# ambassador_attribute_1: "Communication skills. Be able to identify the problems players are having and help them solve them. Also, keep the rest of us informed about what players are saying, what they like and don't like and want more of!"
# ambassador_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll go from there!"
# ambassador_join_note_strong: "Note"
# ambassador_join_note_desc: "One of our top priorities is to build multiplayer where players having difficulty solving levels can summon higher level wizards to help them. This will be a great way for ambassadors to do their thing. We'll keep you posted!"
# more_about_ambassador: "Learn More About Becoming A Helpful Ambassador"
# more_about_ambassador: "Learn More About Becoming an Ambassador"
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
# counselor_introduction_1: "Do you have life experience? A different perspective on things that can help us decide how to shape CodeCombat? Of all these roles, this will probably take the least time, but individually you may make the most difference. We're on the lookout for wisened sages, particularly in areas like: teaching, game development, open source project management, technical recruiting, entrepreneurship, or design."
# counselor_introduction_2: "Or really anything that is relevant to the development of CodeCombat. If you have knowledge and want to share it to help grow this project, then this class might be for you."
# counselor_attribute_1: "Experience, in any of the areas above or something you think might be helpful."
# counselor_attribute_2: "A little bit of free time!"
# counselor_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll put you in our contact list and be in touch when we could use advice (not too often)."
# more_about_counselor: "Learn More About Becoming A Valuable Counselor"
# more_about_counselor: "Learn More About Becoming a Counselor"
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
# diligent_scribes: "Our Diligent Scribes:"
# powerful_archmages: "Our Powerful Archmages:"

View file

@ -71,7 +71,7 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
choose_your_level: "Διάλεξε την πίστα σου"
adventurer_prefix: "Μπορείτε να μεταβείτε σε οποιοδήποτε επίπεδο κάτω, ή να συζητήσετε για τις πίστες στο "
adventurer_forum: "Φόρουμ του \"Τυχοδιώκτη\""
# adventurer_suffix: ""
# adventurer_suffix: "."
campaign_beginner: "Εκστρατεία για Αρχάριους"
campaign_beginner_description: "... στο οποίο μπορείτε να μάθετε τη μαγεία του προγραμματισμού"
campaign_dev: "Τυχαία δυσκολότερα επίπεδα"
@ -90,7 +90,7 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
contribute_suffix: "!"
forum_prefix: "Για οτιδήποτε δημόσιο, δοκίμασε "
forum_page: "το φόρουμ μας"
# forum_suffix: " instead."
# forum_suffix: " instead."
send: "Αποστολή σχολίων"
diplomat_suggestion:
@ -104,6 +104,14 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
# wizard_settings:
# title: "Wizard Settings"
# customize_avatar: "Customize Your Avatar"
# clothes: "Clothes"
# trim: "Trim"
# cloud: "Cloud"
# spell: "Spell"
# boots: "Boots"
# hue: "Hue"
# saturation: "Saturation"
# lightness: "Lightness"
account_settings:
title: "Ρυθμίσεις λογαριασμού"
@ -123,7 +131,7 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
email_subscriptions: "Συνδρομές Email"
email_announcements: "Ανακοινώσεις"
# email_notifications_description: "Get periodic notifications for your account."
# email_announcements_description: "Λάβετε emails για τα τελευταία νέα και τις εξελίξεις του CodeCombat."
email_announcements_description: "Λάβετε emails για τα τελευταία νέα και τις εξελίξεις του CodeCombat."
contributor_emails: "Contributor Class Emails"
contribute_prefix: "Αναζητούμε για ανθρώπους που θέλουν να "
contribute_page: "Σελίδα συνεισφοράς"
@ -150,7 +158,7 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
gravatar_profile_link: "Πλήρη προφίλ \"Gravatar\""
play_level:
level_load_error: "Το επίπεδο δεν μπόρεσε να φορτωθεί"
level_load_error: "Το επίπεδο δεν μπόρεσε να φορτωθεί: "
done: "Έτοιμο"
grid: "Πλέγμα"
customize_wizard: "Προσαρμόστε τον Μάγο"
@ -245,16 +253,16 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
# general:
# and: "and"
name: "Όνομα"
# name: "Name"
# body: "Body"
# version: "Version"
# commit_msg: "Commit Message"
# version_history_for: "Version History for: "
# results: "Results"
# description: "Description"
or: "ή"
email: "Email "
message: "Μήνυμα"
# or: "or"
# email: "Email"
# message: "Message"
# about:
# who_is_codecombat: "Who is CodeCombat?"
@ -352,6 +360,7 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
# alert_account_message_pref: "To subscribe for class emails, you'll need to "
# alert_account_message_suf: "first."
# alert_account_message_create_url: "create an account"
# archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
# archmage_introduction: "One of the best parts about building games is they synthesize so many different things. Graphics, sound, real-time networking, social networking, and of course many of the more common aspects of programming, from low-level database management, and server administration to user facing design and interface building. There's a lot to do, and if you're an experienced programmer with a hankering to really dive into the nitty-gritty of CodeCombat, this class might be for you. We would love to have your help building the best programming game ever."
# class_attributes: "Class Attributes"
# archmage_attribute_1_pref: "Knowledge in "
@ -364,10 +373,12 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
# join_desc_4: "and we'll go from there!"
# join_url_email: "Email us"
# join_url_hipchat: "public HipChat room"
# more_about_archmage: "Learn More About Becoming A Powerful Archmage"
# more_about_archmage: "Learn More About Becoming an Archmage"
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
# artisan_summary_suf: "then this class is for you."
# artisan_introduction_pref: "We must construct additional levels! People be clamoring for more content, and we can only build so many ourselves. Right now your workstation is level one; our level editor is barely usable even by its creators, so be wary. If you have visions of campaigns spanning for-loops to"
# artisan_introduction_suf: "to then this class might be for you."
# artisan_introduction_suf: "then this class might be for you."
# artisan_attribute_1: "Any experience in building content like this would be nice, such as using Blizzard's level editors. But not required!"
# artisan_attribute_2: "A hankering to do a whole lot of testing and iteration. To make good levels, you need to take it to others and watch them play it, and be prepared to find a lot of things to fix."
# artisan_attribute_3: "For the time being, endurance en par with an Adventurer. Our Level Editor is super preliminary and frustrating to use. You have been warned!"
@ -376,46 +387,52 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
# artisan_join_step2: "Create a new level and explore existing levels."
# artisan_join_step3: "Find us in our public HipChat room for help."
# artisan_join_step4: "Post your levels on the forum for feedback."
# more_about_artisan: "Learn More About Becoming A Creative Artisan"
# more_about_artisan: "Learn More About Becoming an Artisan"
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class is for you."
# adventurer_introduction: "Let's be clear about your role: you are the tank. You're going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class might be for you."
# adventurer_attribute_1: "A thirst for learning. You want to learn how to code and we want to teach you how to code. You'll probably be doing most of the teaching in this case, though."
# adventurer_attribute_2: "Charismatic. Be gentle but articulate about what needs improving, and offer suggestions on how to improve."
# adventurer_join_pref: "Either get together with (or recruit!) an Artisan and work with them, or check the box below to receive emails when there are new levels to test. We'll also be posting about levels to review on our networks like"
# adventurer_forum_url: "our forum"
# adventurer_join_suf: "so if you prefer to be notified those ways, sign up there!"
# more_about_adventurer: "Learn More About Becoming A Brave Adventurer"
# more_about_adventurer: "Learn More About Becoming an Adventurer"
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
# scribe_introduction_pref: "CodeCombat isn't just going to be a bunch of levels. It will also include a resource for knowledge, a wiki of programming concepts that levels can hook into. That way rather than each Artisan having to describe in detail what a comparison operator is, they can simply link their level to the Article describing them that is already written for the player's edification. Something along the lines of what the "
# scribe_introduction_url_mozilla: "Mozilla Developer Network"
# scribe_introduction_suf: " has built. If your idea of fun is articulating the concepts of programming in Markdown form, then this class might be for you."
# scribe_attribute_1: "Skill in words is pretty much all you need. Not only grammar and spelling, but able to convey complicated ideas to others."
# contact_us_url: "Contact us"
# scribe_join_description: "tell us a little about yourself, your experience with programming and what sort of things you'd like to write about. We'll go from there!"
# more_about_scribe: "Learn More About Becoming A Diligent Scribe"
# more_about_scribe: "Learn More About Becoming a Scribe"
# scribe_subscribe_desc: "Get emails about article writing announcements."
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
# diplomat_introduction_pref: "So, if there's one thing we learned from the "
# diplomat_launch_url: "launch in October"
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries, particularly Brazil! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_attribute_1: "Fluency in English and the language you would like to translate to. When conveying complicated ideas, it's important to have a strong grasp in both!"
# diplomat_join_pref: "We've started a lot of initial translations at "
# diplomat_doc_url: "this forum post"
# diplomat_join_suf: "so check it out and add things for your language. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming A Great Diplomat"
# diplomat_join_pref_github: "Find your language locale file "
# diplomat_github_url: "on GitHub"
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming a Diplomat"
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
# ambassador_introduction: "This is a community we're building, and you are the connections. We've got Olark chats, emails, and social networks with lots of people to talk with and help get acquainted with the game and learn from. If you want to help people get involved and have fun, and get a good feel of the pulse of CodeCombat and where we're going, then this class might be for you."
# ambassador_attribute_1: "Communication skills. Be able to identify the problems players are having and help them solve them. Also, keep the rest of us informed about what players are saying, what they like and don't like and want more of!"
# ambassador_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll go from there!"
# ambassador_join_note_strong: "Note"
# ambassador_join_note_desc: "One of our top priorities is to build multiplayer where players having difficulty solving levels can summon higher level wizards to help them. This will be a great way for ambassadors to do their thing. We'll keep you posted!"
# more_about_ambassador: "Learn More About Becoming A Helpful Ambassador"
# more_about_ambassador: "Learn More About Becoming an Ambassador"
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
# counselor_introduction_1: "Do you have life experience? A different perspective on things that can help us decide how to shape CodeCombat? Of all these roles, this will probably take the least time, but individually you may make the most difference. We're on the lookout for wisened sages, particularly in areas like: teaching, game development, open source project management, technical recruiting, entrepreneurship, or design."
# counselor_introduction_2: "Or really anything that is relevant to the development of CodeCombat. If you have knowledge and want to share it to help grow this project, then this class might be for you."
# counselor_attribute_1: "Experience, in any of the areas above or something you think might be helpful."
# counselor_attribute_2: "A little bit of free time!"
# counselor_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll put you in our contact list and be in touch when we could use advice (not too often)."
# more_about_counselor: "Learn More About Becoming A Valuable Counselor"
# more_about_counselor: "Learn More About Becoming a Counselor"
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
# diligent_scribes: "Our Diligent Scribes:"
# powerful_archmages: "Our Powerful Archmages:"

View file

@ -104,6 +104,14 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English
# wizard_settings:
# title: "Wizard Settings"
# customize_avatar: "Customize Your Avatar"
# clothes: "Clothes"
# trim: "Trim"
# cloud: "Cloud"
# spell: "Spell"
# boots: "Boots"
# hue: "Hue"
# saturation: "Saturation"
# lightness: "Lightness"
# account_settings:
# title: "Account Settings"
@ -150,7 +158,7 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English
# gravatar_profile_link: "Full Gravatar Profile"
# play_level:
# level_load_error: "Level could not be loaded."
# level_load_error: "Level could not be loaded: "
# done: "Done"
# grid: "Grid"
# customize_wizard: "Customize Wizard"
@ -173,7 +181,7 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English
# victory_go_home: "Go Home"
# victory_review: "Tell us more!"
# victory_hour_of_code_done: "Are You Done?"
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
# multiplayer_title: "Multiplayer Settings"
# multiplayer_link_description: "Give this link to anyone to have them join you."
# multiplayer_hint_label: "Hint:"
@ -183,7 +191,7 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English
# tome_minion_spells: "Your Minions' Spells"
# tome_read_only_spells: "Read-Only Spells"
# tome_other_units: "Other Units"
# tome_cast_button_castable: "Cast"
# tome_cast_button_castable: "Cast Spell"
# tome_cast_button_casting: "Casting"
# tome_cast_button_cast: "Spell Cast"
# tome_autocast_delay: "Autocast Delay"
@ -352,6 +360,7 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English
# alert_account_message_pref: "To subscribe for class emails, you'll need to "
# alert_account_message_suf: "first."
# alert_account_message_create_url: "create an account"
# archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
# archmage_introduction: "One of the best parts about building games is they synthesize so many different things. Graphics, sound, real-time networking, social networking, and of course many of the more common aspects of programming, from low-level database management, and server administration to user facing design and interface building. There's a lot to do, and if you're an experienced programmer with a hankering to really dive into the nitty-gritty of CodeCombat, this class might be for you. We would love to have your help building the best programming game ever."
# class_attributes: "Class Attributes"
# archmage_attribute_1_pref: "Knowledge in "
@ -364,10 +373,12 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English
# join_desc_4: "and we'll go from there!"
# join_url_email: "Email us"
# join_url_hipchat: "public HipChat room"
# more_about_archmage: "Learn More About Becoming A Powerful Archmage"
# more_about_archmage: "Learn More About Becoming an Archmage"
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
# artisan_summary_suf: "then this class is for you."
# artisan_introduction_pref: "We must construct additional levels! People be clamoring for more content, and we can only build so many ourselves. Right now your workstation is level one; our level editor is barely usable even by its creators, so be wary. If you have visions of campaigns spanning for-loops to"
# artisan_introduction_suf: "to then this class might be for you."
# artisan_introduction_suf: "then this class might be for you."
# artisan_attribute_1: "Any experience in building content like this would be nice, such as using Blizzard's level editors. But not required!"
# artisan_attribute_2: "A hankering to do a whole lot of testing and iteration. To make good levels, you need to take it to others and watch them play it, and be prepared to find a lot of things to fix."
# artisan_attribute_3: "For the time being, endurance en par with an Adventurer. Our Level Editor is super preliminary and frustrating to use. You have been warned!"
@ -376,46 +387,52 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English
# artisan_join_step2: "Create a new level and explore existing levels."
# artisan_join_step3: "Find us in our public HipChat room for help."
# artisan_join_step4: "Post your levels on the forum for feedback."
# more_about_artisan: "Learn More About Becoming A Creative Artisan"
# more_about_artisan: "Learn More About Becoming an Artisan"
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class is for you."
# adventurer_introduction: "Let's be clear about your role: you are the tank. You're going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class might be for you."
# adventurer_attribute_1: "A thirst for learning. You want to learn how to code and we want to teach you how to code. You'll probably be doing most of the teaching in this case, though."
# adventurer_attribute_2: "Charismatic. Be gentle but articulate about what needs improving, and offer suggestions on how to improve."
# adventurer_join_pref: "Either get together with (or recruit!) an Artisan and work with them, or check the box below to receive emails when there are new levels to test. We'll also be posting about levels to review on our networks like"
# adventurer_forum_url: "our forum"
# adventurer_join_suf: "so if you prefer to be notified those ways, sign up there!"
# more_about_adventurer: "Learn More About Becoming A Brave Adventurer"
# more_about_adventurer: "Learn More About Becoming an Adventurer"
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
# scribe_introduction_pref: "CodeCombat isn't just going to be a bunch of levels. It will also include a resource for knowledge, a wiki of programming concepts that levels can hook into. That way rather than each Artisan having to describe in detail what a comparison operator is, they can simply link their level to the Article describing them that is already written for the player's edification. Something along the lines of what the "
# scribe_introduction_url_mozilla: "Mozilla Developer Network"
# scribe_introduction_suf: " has built. If your idea of fun is articulating the concepts of programming in Markdown form, then this class might be for you."
# scribe_attribute_1: "Skill in words is pretty much all you need. Not only grammar and spelling, but able to convey complicated ideas to others."
# contact_us_url: "Contact us"
# scribe_join_description: "tell us a little about yourself, your experience with programming and what sort of things you'd like to write about. We'll go from there!"
# more_about_scribe: "Learn More About Becoming A Diligent Scribe"
# more_about_scribe: "Learn More About Becoming a Scribe"
# scribe_subscribe_desc: "Get emails about article writing announcements."
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
# diplomat_introduction_pref: "So, if there's one thing we learned from the "
# diplomat_launch_url: "launch in October"
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries, particularly Brazil! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_attribute_1: "Fluency in English and the language you would like to translate to. When conveying complicated ideas, it's important to have a strong grasp in both!"
# diplomat_join_pref: "We've started a lot of initial translations at "
# diplomat_doc_url: "this forum post"
# diplomat_join_suf: "so check it out and add things for your language. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming A Great Diplomat"
# diplomat_join_pref_github: "Find your language locale file "
# diplomat_github_url: "on GitHub"
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming a Diplomat"
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
# ambassador_introduction: "This is a community we're building, and you are the connections. We've got Olark chats, emails, and social networks with lots of people to talk with and help get acquainted with the game and learn from. If you want to help people get involved and have fun, and get a good feel of the pulse of CodeCombat and where we're going, then this class might be for you."
# ambassador_attribute_1: "Communication skills. Be able to identify the problems players are having and help them solve them. Also, keep the rest of us informed about what players are saying, what they like and don't like and want more of!"
# ambassador_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll go from there!"
# ambassador_join_note_strong: "Note"
# ambassador_join_note_desc: "One of our top priorities is to build multiplayer where players having difficulty solving levels can summon higher level wizards to help them. This will be a great way for ambassadors to do their thing. We'll keep you posted!"
# more_about_ambassador: "Learn More About Becoming A Helpful Ambassador"
# more_about_ambassador: "Learn More About Becoming an Ambassador"
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
# counselor_introduction_1: "Do you have life experience? A different perspective on things that can help us decide how to shape CodeCombat? Of all these roles, this will probably take the least time, but individually you may make the most difference. We're on the lookout for wisened sages, particularly in areas like: teaching, game development, open source project management, technical recruiting, entrepreneurship, or design."
# counselor_introduction_2: "Or really anything that is relevant to the development of CodeCombat. If you have knowledge and want to share it to help grow this project, then this class might be for you."
# counselor_attribute_1: "Experience, in any of the areas above or something you think might be helpful."
# counselor_attribute_2: "A little bit of free time!"
# counselor_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll put you in our contact list and be in touch when we could use advice (not too often)."
# more_about_counselor: "Learn More About Becoming A Valuable Counselor"
# more_about_counselor: "Learn More About Becoming a Counselor"
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
# diligent_scribes: "Our Diligent Scribes:"
# powerful_archmages: "Our Powerful Archmages:"

View file

@ -104,6 +104,14 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English
# wizard_settings:
# title: "Wizard Settings"
# customize_avatar: "Customize Your Avatar"
# clothes: "Clothes"
# trim: "Trim"
# cloud: "Cloud"
# spell: "Spell"
# boots: "Boots"
# hue: "Hue"
# saturation: "Saturation"
# lightness: "Lightness"
# account_settings:
# title: "Account Settings"
@ -150,7 +158,7 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English
# gravatar_profile_link: "Full Gravatar Profile"
# play_level:
# level_load_error: "Level could not be loaded."
# level_load_error: "Level could not be loaded: "
# done: "Done"
# grid: "Grid"
# customize_wizard: "Customize Wizard"
@ -173,7 +181,7 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English
# victory_go_home: "Go Home"
# victory_review: "Tell us more!"
# victory_hour_of_code_done: "Are You Done?"
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
# multiplayer_title: "Multiplayer Settings"
# multiplayer_link_description: "Give this link to anyone to have them join you."
# multiplayer_hint_label: "Hint:"
@ -183,7 +191,7 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English
# tome_minion_spells: "Your Minions' Spells"
# tome_read_only_spells: "Read-Only Spells"
# tome_other_units: "Other Units"
# tome_cast_button_castable: "Cast"
# tome_cast_button_castable: "Cast Spell"
# tome_cast_button_casting: "Casting"
# tome_cast_button_cast: "Spell Cast"
# tome_autocast_delay: "Autocast Delay"
@ -352,6 +360,7 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English
# alert_account_message_pref: "To subscribe for class emails, you'll need to "
# alert_account_message_suf: "first."
# alert_account_message_create_url: "create an account"
# archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
# archmage_introduction: "One of the best parts about building games is they synthesize so many different things. Graphics, sound, real-time networking, social networking, and of course many of the more common aspects of programming, from low-level database management, and server administration to user facing design and interface building. There's a lot to do, and if you're an experienced programmer with a hankering to really dive into the nitty-gritty of CodeCombat, this class might be for you. We would love to have your help building the best programming game ever."
# class_attributes: "Class Attributes"
# archmage_attribute_1_pref: "Knowledge in "
@ -364,10 +373,12 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English
# join_desc_4: "and we'll go from there!"
# join_url_email: "Email us"
# join_url_hipchat: "public HipChat room"
# more_about_archmage: "Learn More About Becoming A Powerful Archmage"
# more_about_archmage: "Learn More About Becoming an Archmage"
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
# artisan_summary_suf: "then this class is for you."
# artisan_introduction_pref: "We must construct additional levels! People be clamoring for more content, and we can only build so many ourselves. Right now your workstation is level one; our level editor is barely usable even by its creators, so be wary. If you have visions of campaigns spanning for-loops to"
# artisan_introduction_suf: "to then this class might be for you."
# artisan_introduction_suf: "then this class might be for you."
# artisan_attribute_1: "Any experience in building content like this would be nice, such as using Blizzard's level editors. But not required!"
# artisan_attribute_2: "A hankering to do a whole lot of testing and iteration. To make good levels, you need to take it to others and watch them play it, and be prepared to find a lot of things to fix."
# artisan_attribute_3: "For the time being, endurance en par with an Adventurer. Our Level Editor is super preliminary and frustrating to use. You have been warned!"
@ -376,46 +387,52 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English
# artisan_join_step2: "Create a new level and explore existing levels."
# artisan_join_step3: "Find us in our public HipChat room for help."
# artisan_join_step4: "Post your levels on the forum for feedback."
# more_about_artisan: "Learn More About Becoming A Creative Artisan"
# more_about_artisan: "Learn More About Becoming an Artisan"
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class is for you."
# adventurer_introduction: "Let's be clear about your role: you are the tank. You're going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class might be for you."
# adventurer_attribute_1: "A thirst for learning. You want to learn how to code and we want to teach you how to code. You'll probably be doing most of the teaching in this case, though."
# adventurer_attribute_2: "Charismatic. Be gentle but articulate about what needs improving, and offer suggestions on how to improve."
# adventurer_join_pref: "Either get together with (or recruit!) an Artisan and work with them, or check the box below to receive emails when there are new levels to test. We'll also be posting about levels to review on our networks like"
# adventurer_forum_url: "our forum"
# adventurer_join_suf: "so if you prefer to be notified those ways, sign up there!"
# more_about_adventurer: "Learn More About Becoming A Brave Adventurer"
# more_about_adventurer: "Learn More About Becoming an Adventurer"
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
# scribe_introduction_pref: "CodeCombat isn't just going to be a bunch of levels. It will also include a resource for knowledge, a wiki of programming concepts that levels can hook into. That way rather than each Artisan having to describe in detail what a comparison operator is, they can simply link their level to the Article describing them that is already written for the player's edification. Something along the lines of what the "
# scribe_introduction_url_mozilla: "Mozilla Developer Network"
# scribe_introduction_suf: " has built. If your idea of fun is articulating the concepts of programming in Markdown form, then this class might be for you."
# scribe_attribute_1: "Skill in words is pretty much all you need. Not only grammar and spelling, but able to convey complicated ideas to others."
# contact_us_url: "Contact us"
# scribe_join_description: "tell us a little about yourself, your experience with programming and what sort of things you'd like to write about. We'll go from there!"
# more_about_scribe: "Learn More About Becoming A Diligent Scribe"
# more_about_scribe: "Learn More About Becoming a Scribe"
# scribe_subscribe_desc: "Get emails about article writing announcements."
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
# diplomat_introduction_pref: "So, if there's one thing we learned from the "
# diplomat_launch_url: "launch in October"
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries, particularly Brazil! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_attribute_1: "Fluency in English and the language you would like to translate to. When conveying complicated ideas, it's important to have a strong grasp in both!"
# diplomat_join_pref: "We've started a lot of initial translations at "
# diplomat_doc_url: "this forum post"
# diplomat_join_suf: "so check it out and add things for your language. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming A Great Diplomat"
# diplomat_join_pref_github: "Find your language locale file "
# diplomat_github_url: "on GitHub"
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming a Diplomat"
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
# ambassador_introduction: "This is a community we're building, and you are the connections. We've got Olark chats, emails, and social networks with lots of people to talk with and help get acquainted with the game and learn from. If you want to help people get involved and have fun, and get a good feel of the pulse of CodeCombat and where we're going, then this class might be for you."
# ambassador_attribute_1: "Communication skills. Be able to identify the problems players are having and help them solve them. Also, keep the rest of us informed about what players are saying, what they like and don't like and want more of!"
# ambassador_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll go from there!"
# ambassador_join_note_strong: "Note"
# ambassador_join_note_desc: "One of our top priorities is to build multiplayer where players having difficulty solving levels can summon higher level wizards to help them. This will be a great way for ambassadors to do their thing. We'll keep you posted!"
# more_about_ambassador: "Learn More About Becoming A Helpful Ambassador"
# more_about_ambassador: "Learn More About Becoming an Ambassador"
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
# counselor_introduction_1: "Do you have life experience? A different perspective on things that can help us decide how to shape CodeCombat? Of all these roles, this will probably take the least time, but individually you may make the most difference. We're on the lookout for wisened sages, particularly in areas like: teaching, game development, open source project management, technical recruiting, entrepreneurship, or design."
# counselor_introduction_2: "Or really anything that is relevant to the development of CodeCombat. If you have knowledge and want to share it to help grow this project, then this class might be for you."
# counselor_attribute_1: "Experience, in any of the areas above or something you think might be helpful."
# counselor_attribute_2: "A little bit of free time!"
# counselor_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll put you in our contact list and be in touch when we could use advice (not too often)."
# more_about_counselor: "Learn More About Becoming A Valuable Counselor"
# more_about_counselor: "Learn More About Becoming a Counselor"
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
# diligent_scribes: "Our Diligent Scribes:"
# powerful_archmages: "Our Powerful Archmages:"

View file

@ -104,6 +104,14 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English
# wizard_settings:
# title: "Wizard Settings"
# customize_avatar: "Customize Your Avatar"
# clothes: "Clothes"
# trim: "Trim"
# cloud: "Cloud"
# spell: "Spell"
# boots: "Boots"
# hue: "Hue"
# saturation: "Saturation"
# lightness: "Lightness"
# account_settings:
# title: "Account Settings"
@ -150,7 +158,7 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English
# gravatar_profile_link: "Full Gravatar Profile"
# play_level:
# level_load_error: "Level could not be loaded."
# level_load_error: "Level could not be loaded: "
# done: "Done"
# grid: "Grid"
# customize_wizard: "Customize Wizard"
@ -173,7 +181,7 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English
# victory_go_home: "Go Home"
# victory_review: "Tell us more!"
# victory_hour_of_code_done: "Are You Done?"
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
# multiplayer_title: "Multiplayer Settings"
# multiplayer_link_description: "Give this link to anyone to have them join you."
# multiplayer_hint_label: "Hint:"
@ -183,7 +191,7 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English
# tome_minion_spells: "Your Minions' Spells"
# tome_read_only_spells: "Read-Only Spells"
# tome_other_units: "Other Units"
# tome_cast_button_castable: "Cast"
# tome_cast_button_castable: "Cast Spell"
# tome_cast_button_casting: "Casting"
# tome_cast_button_cast: "Spell Cast"
# tome_autocast_delay: "Autocast Delay"
@ -352,6 +360,7 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English
# alert_account_message_pref: "To subscribe for class emails, you'll need to "
# alert_account_message_suf: "first."
# alert_account_message_create_url: "create an account"
# archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
# archmage_introduction: "One of the best parts about building games is they synthesize so many different things. Graphics, sound, real-time networking, social networking, and of course many of the more common aspects of programming, from low-level database management, and server administration to user facing design and interface building. There's a lot to do, and if you're an experienced programmer with a hankering to really dive into the nitty-gritty of CodeCombat, this class might be for you. We would love to have your help building the best programming game ever."
# class_attributes: "Class Attributes"
# archmage_attribute_1_pref: "Knowledge in "
@ -364,10 +373,12 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English
# join_desc_4: "and we'll go from there!"
# join_url_email: "Email us"
# join_url_hipchat: "public HipChat room"
# more_about_archmage: "Learn More About Becoming A Powerful Archmage"
# more_about_archmage: "Learn More About Becoming an Archmage"
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
# artisan_summary_suf: "then this class is for you."
# artisan_introduction_pref: "We must construct additional levels! People be clamoring for more content, and we can only build so many ourselves. Right now your workstation is level one; our level editor is barely usable even by its creators, so be wary. If you have visions of campaigns spanning for-loops to"
# artisan_introduction_suf: "to then this class might be for you."
# artisan_introduction_suf: "then this class might be for you."
# artisan_attribute_1: "Any experience in building content like this would be nice, such as using Blizzard's level editors. But not required!"
# artisan_attribute_2: "A hankering to do a whole lot of testing and iteration. To make good levels, you need to take it to others and watch them play it, and be prepared to find a lot of things to fix."
# artisan_attribute_3: "For the time being, endurance en par with an Adventurer. Our Level Editor is super preliminary and frustrating to use. You have been warned!"
@ -376,46 +387,52 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English
# artisan_join_step2: "Create a new level and explore existing levels."
# artisan_join_step3: "Find us in our public HipChat room for help."
# artisan_join_step4: "Post your levels on the forum for feedback."
# more_about_artisan: "Learn More About Becoming A Creative Artisan"
# more_about_artisan: "Learn More About Becoming an Artisan"
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class is for you."
# adventurer_introduction: "Let's be clear about your role: you are the tank. You're going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class might be for you."
# adventurer_attribute_1: "A thirst for learning. You want to learn how to code and we want to teach you how to code. You'll probably be doing most of the teaching in this case, though."
# adventurer_attribute_2: "Charismatic. Be gentle but articulate about what needs improving, and offer suggestions on how to improve."
# adventurer_join_pref: "Either get together with (or recruit!) an Artisan and work with them, or check the box below to receive emails when there are new levels to test. We'll also be posting about levels to review on our networks like"
# adventurer_forum_url: "our forum"
# adventurer_join_suf: "so if you prefer to be notified those ways, sign up there!"
# more_about_adventurer: "Learn More About Becoming A Brave Adventurer"
# more_about_adventurer: "Learn More About Becoming an Adventurer"
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
# scribe_introduction_pref: "CodeCombat isn't just going to be a bunch of levels. It will also include a resource for knowledge, a wiki of programming concepts that levels can hook into. That way rather than each Artisan having to describe in detail what a comparison operator is, they can simply link their level to the Article describing them that is already written for the player's edification. Something along the lines of what the "
# scribe_introduction_url_mozilla: "Mozilla Developer Network"
# scribe_introduction_suf: " has built. If your idea of fun is articulating the concepts of programming in Markdown form, then this class might be for you."
# scribe_attribute_1: "Skill in words is pretty much all you need. Not only grammar and spelling, but able to convey complicated ideas to others."
# contact_us_url: "Contact us"
# scribe_join_description: "tell us a little about yourself, your experience with programming and what sort of things you'd like to write about. We'll go from there!"
# more_about_scribe: "Learn More About Becoming A Diligent Scribe"
# more_about_scribe: "Learn More About Becoming a Scribe"
# scribe_subscribe_desc: "Get emails about article writing announcements."
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
# diplomat_introduction_pref: "So, if there's one thing we learned from the "
# diplomat_launch_url: "launch in October"
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries, particularly Brazil! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_attribute_1: "Fluency in English and the language you would like to translate to. When conveying complicated ideas, it's important to have a strong grasp in both!"
# diplomat_join_pref: "We've started a lot of initial translations at "
# diplomat_doc_url: "this forum post"
# diplomat_join_suf: "so check it out and add things for your language. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming A Great Diplomat"
# diplomat_join_pref_github: "Find your language locale file "
# diplomat_github_url: "on GitHub"
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming a Diplomat"
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
# ambassador_introduction: "This is a community we're building, and you are the connections. We've got Olark chats, emails, and social networks with lots of people to talk with and help get acquainted with the game and learn from. If you want to help people get involved and have fun, and get a good feel of the pulse of CodeCombat and where we're going, then this class might be for you."
# ambassador_attribute_1: "Communication skills. Be able to identify the problems players are having and help them solve them. Also, keep the rest of us informed about what players are saying, what they like and don't like and want more of!"
# ambassador_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll go from there!"
# ambassador_join_note_strong: "Note"
# ambassador_join_note_desc: "One of our top priorities is to build multiplayer where players having difficulty solving levels can summon higher level wizards to help them. This will be a great way for ambassadors to do their thing. We'll keep you posted!"
# more_about_ambassador: "Learn More About Becoming A Helpful Ambassador"
# more_about_ambassador: "Learn More About Becoming an Ambassador"
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
# counselor_introduction_1: "Do you have life experience? A different perspective on things that can help us decide how to shape CodeCombat? Of all these roles, this will probably take the least time, but individually you may make the most difference. We're on the lookout for wisened sages, particularly in areas like: teaching, game development, open source project management, technical recruiting, entrepreneurship, or design."
# counselor_introduction_2: "Or really anything that is relevant to the development of CodeCombat. If you have knowledge and want to share it to help grow this project, then this class might be for you."
# counselor_attribute_1: "Experience, in any of the areas above or something you think might be helpful."
# counselor_attribute_2: "A little bit of free time!"
# counselor_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll put you in our contact list and be in touch when we could use advice (not too often)."
# more_about_counselor: "Learn More About Becoming A Valuable Counselor"
# more_about_counselor: "Learn More About Becoming a Counselor"
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
# diligent_scribes: "Our Diligent Scribes:"
# powerful_archmages: "Our Powerful Archmages:"

View file

@ -104,6 +104,14 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr
wizard_settings:
title: "Wizard Settings"
customize_avatar: "Customize Your Avatar"
clothes: "Clothes"
trim: "Trim"
cloud: "Cloud"
spell: "Spell"
boots: "Boots"
hue: "Hue"
saturation: "Saturation"
lightness: "Lightness"
account_settings:
title: "Account Settings"
@ -150,7 +158,7 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr
gravatar_profile_link: "Full Gravatar Profile"
play_level:
level_load_error: "Level could not be loaded."
level_load_error: "Level could not be loaded: "
done: "Done"
grid: "Grid"
customize_wizard: "Customize Wizard"
@ -173,7 +181,7 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr
victory_go_home: "Go Home"
victory_review: "Tell us more!"
victory_hour_of_code_done: "Are You Done?"
victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
multiplayer_title: "Multiplayer Settings"
multiplayer_link_description: "Give this link to anyone to have them join you."
multiplayer_hint_label: "Hint:"
@ -183,7 +191,7 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr
tome_minion_spells: "Your Minions' Spells"
tome_read_only_spells: "Read-Only Spells"
tome_other_units: "Other Units"
tome_cast_button_castable: "Cast"
tome_cast_button_castable: "Cast Spell"
tome_cast_button_casting: "Casting"
tome_cast_button_cast: "Spell Cast"
tome_autocast_delay: "Autocast Delay"
@ -352,6 +360,7 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr
alert_account_message_pref: "To subscribe for class emails, you'll need to "
alert_account_message_suf: "first."
alert_account_message_create_url: "create an account"
archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
archmage_introduction: "One of the best parts about building games is they synthesize so many different things. Graphics, sound, real-time networking, social networking, and of course many of the more common aspects of programming, from low-level database management, and server administration to user facing design and interface building. There's a lot to do, and if you're an experienced programmer with a hankering to really dive into the nitty-gritty of CodeCombat, this class might be for you. We would love to have your help building the best programming game ever."
class_attributes: "Class Attributes"
archmage_attribute_1_pref: "Knowledge in "
@ -364,10 +373,12 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr
join_desc_4: "and we'll go from there!"
join_url_email: "Email us"
join_url_hipchat: "public HipChat room"
more_about_archmage: "Learn More About Becoming A Powerful Archmage"
more_about_archmage: "Learn More About Becoming an Archmage"
archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
artisan_summary_suf: "then this class is for you."
artisan_introduction_pref: "We must construct additional levels! People be clamoring for more content, and we can only build so many ourselves. Right now your workstation is level one; our level editor is barely usable even by its creators, so be wary. If you have visions of campaigns spanning for-loops to"
artisan_introduction_suf: "to then this class might be for you."
artisan_introduction_suf: "then this class might be for you."
artisan_attribute_1: "Any experience in building content like this would be nice, such as using Blizzard's level editors. But not required!"
artisan_attribute_2: "A hankering to do a whole lot of testing and iteration. To make good levels, you need to take it to others and watch them play it, and be prepared to find a lot of things to fix."
artisan_attribute_3: "For the time being, endurance en par with an Adventurer. Our Level Editor is super preliminary and frustrating to use. You have been warned!"
@ -376,46 +387,52 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr
artisan_join_step2: "Create a new level and explore existing levels."
artisan_join_step3: "Find us in our public HipChat room for help."
artisan_join_step4: "Post your levels on the forum for feedback."
more_about_artisan: "Learn More About Becoming A Creative Artisan"
more_about_artisan: "Learn More About Becoming an Artisan"
artisan_subscribe_desc: "Get emails on level editor updates and announcements."
adventurer_sumamry: "Let us be clear about your role: you are the tank. You are going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class is for you."
adventurer_introduction: "Let's be clear about your role: you are the tank. You're going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class might be for you."
adventurer_attribute_1: "A thirst for learning. You want to learn how to code and we want to teach you how to code. You'll probably be doing most of the teaching in this case, though."
adventurer_attribute_2: "Charismatic. Be gentle but articulate about what needs improving, and offer suggestions on how to improve."
adventurer_join_pref: "Either get together with (or recruit!) an Artisan and work with them, or check the box below to receive emails when there are new levels to test. We'll also be posting about levels to review on our networks like"
adventurer_forum_url: "our forum"
adventurer_join_suf: "so if you prefer to be notified those ways, sign up there!"
more_about_adventurer: "Learn More About Becoming A Brave Adventurer"
more_about_adventurer: "Learn More About Becoming an Adventurer"
adventurer_subscribe_desc: "Get emails when there are new levels to test."
scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
scribe_introduction_pref: "CodeCombat isn't just going to be a bunch of levels. It will also include a resource for knowledge, a wiki of programming concepts that levels can hook into. That way rather than each Artisan having to describe in detail what a comparison operator is, they can simply link their level to the Article describing them that is already written for the player's edification. Something along the lines of what the "
scribe_introduction_url_mozilla: "Mozilla Developer Network"
scribe_introduction_suf: " has built. If your idea of fun is articulating the concepts of programming in Markdown form, then this class might be for you."
scribe_attribute_1: "Skill in words is pretty much all you need. Not only grammar and spelling, but able to convey complicated ideas to others."
contact_us_url: "Contact us"
scribe_join_description: "tell us a little about yourself, your experience with programming and what sort of things you'd like to write about. We'll go from there!"
more_about_scribe: "Learn More About Becoming A Diligent Scribe"
more_about_scribe: "Learn More About Becoming a Scribe"
scribe_subscribe_desc: "Get emails about article writing announcements."
diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
diplomat_introduction_pref: "So, if there's one thing we learned from the "
diplomat_launch_url: "launch in October"
diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries, particularly Brazil! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
diplomat_attribute_1: "Fluency in English and the language you would like to translate to. When conveying complicated ideas, it's important to have a strong grasp in both!"
diplomat_join_pref: "We've started a lot of initial translations at "
diplomat_doc_url: "this forum post"
diplomat_join_suf: "so check it out and add things for your language. Also, check this box below to keep up-to-date on new internationalization developments!"
more_about_diplomat: "Learn More About Becoming A Great Diplomat"
diplomat_join_pref_github: "Find your language locale file "
diplomat_github_url: "on GitHub"
diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
more_about_diplomat: "Learn More About Becoming a Diplomat"
diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
ambassador_introduction: "This is a community we're building, and you are the connections. We've got Olark chats, emails, and social networks with lots of people to talk with and help get acquainted with the game and learn from. If you want to help people get involved and have fun, and get a good feel of the pulse of CodeCombat and where we're going, then this class might be for you."
ambassador_attribute_1: "Communication skills. Be able to identify the problems players are having and help them solve them. Also, keep the rest of us informed about what players are saying, what they like and don't like and want more of!"
ambassador_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll go from there!"
ambassador_join_note_strong: "Note"
ambassador_join_note_desc: "One of our top priorities is to build multiplayer where players having difficulty solving levels can summon higher level wizards to help them. This will be a great way for ambassadors to do their thing. We'll keep you posted!"
more_about_ambassador: "Learn More About Becoming A Helpful Ambassador"
more_about_ambassador: "Learn More About Becoming an Ambassador"
ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
counselor_introduction_1: "Do you have life experience? A different perspective on things that can help us decide how to shape CodeCombat? Of all these roles, this will probably take the least time, but individually you may make the most difference. We're on the lookout for wisened sages, particularly in areas like: teaching, game development, open source project management, technical recruiting, entrepreneurship, or design."
counselor_introduction_2: "Or really anything that is relevant to the development of CodeCombat. If you have knowledge and want to share it to help grow this project, then this class might be for you."
counselor_attribute_1: "Experience, in any of the areas above or something you think might be helpful."
counselor_attribute_2: "A little bit of free time!"
counselor_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll put you in our contact list and be in touch when we could use advice (not too often)."
more_about_counselor: "Learn More About Becoming A Valuable Counselor"
more_about_counselor: "Learn More About Becoming a Counselor"
changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
diligent_scribes: "Our Diligent Scribes:"
powerful_archmages: "Our Powerful Archmages:"

View file

@ -104,6 +104,14 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip
# wizard_settings:
# title: "Wizard Settings"
# customize_avatar: "Customize Your Avatar"
# clothes: "Clothes"
# trim: "Trim"
# cloud: "Cloud"
# spell: "Spell"
# boots: "Boots"
# hue: "Hue"
# saturation: "Saturation"
# lightness: "Lightness"
account_settings:
title: "Configuración de la Cuenta"
@ -150,7 +158,7 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip
gravatar_profile_link: "Perfil Gravatar Completo"
play_level:
level_load_error: "El nivel no puede ser cargado."
level_load_error: "El nivel no puede ser cargado: "
done: "Listo"
grid: "Cuadricula"
customize_wizard: "Personalizar Hechicero"
@ -245,16 +253,16 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip
# general:
# and: "and"
or: "o"
name: "Nombre"
# name: "Name"
# body: "Body"
# version: "Version"
# commit_msg: "Commit Message"
# version_history_for: "Version History for: "
# results: "Results"
# description: "Description"
email: "Email"
message: "Mensaje"
# or: "or"
# email: "Email"
# message: "Message"
# about:
# who_is_codecombat: "Who is CodeCombat?"
@ -352,6 +360,7 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip
# alert_account_message_pref: "To subscribe for class emails, you'll need to "
# alert_account_message_suf: "first."
# alert_account_message_create_url: "create an account"
# archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
# archmage_introduction: "One of the best parts about building games is they synthesize so many different things. Graphics, sound, real-time networking, social networking, and of course many of the more common aspects of programming, from low-level database management, and server administration to user facing design and interface building. There's a lot to do, and if you're an experienced programmer with a hankering to really dive into the nitty-gritty of CodeCombat, this class might be for you. We would love to have your help building the best programming game ever."
# class_attributes: "Class Attributes"
# archmage_attribute_1_pref: "Knowledge in "
@ -364,10 +373,12 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip
# join_desc_4: "and we'll go from there!"
# join_url_email: "Email us"
# join_url_hipchat: "public HipChat room"
# more_about_archmage: "Learn More About Becoming A Powerful Archmage"
# more_about_archmage: "Learn More About Becoming an Archmage"
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
# artisan_summary_suf: "then this class is for you."
# artisan_introduction_pref: "We must construct additional levels! People be clamoring for more content, and we can only build so many ourselves. Right now your workstation is level one; our level editor is barely usable even by its creators, so be wary. If you have visions of campaigns spanning for-loops to"
# artisan_introduction_suf: "to then this class might be for you."
# artisan_introduction_suf: "then this class might be for you."
# artisan_attribute_1: "Any experience in building content like this would be nice, such as using Blizzard's level editors. But not required!"
# artisan_attribute_2: "A hankering to do a whole lot of testing and iteration. To make good levels, you need to take it to others and watch them play it, and be prepared to find a lot of things to fix."
# artisan_attribute_3: "For the time being, endurance en par with an Adventurer. Our Level Editor is super preliminary and frustrating to use. You have been warned!"
@ -376,46 +387,52 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip
# artisan_join_step2: "Create a new level and explore existing levels."
# artisan_join_step3: "Find us in our public HipChat room for help."
# artisan_join_step4: "Post your levels on the forum for feedback."
# more_about_artisan: "Learn More About Becoming A Creative Artisan"
# more_about_artisan: "Learn More About Becoming an Artisan"
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class is for you."
# adventurer_introduction: "Let's be clear about your role: you are the tank. You're going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class might be for you."
# adventurer_attribute_1: "A thirst for learning. You want to learn how to code and we want to teach you how to code. You'll probably be doing most of the teaching in this case, though."
# adventurer_attribute_2: "Charismatic. Be gentle but articulate about what needs improving, and offer suggestions on how to improve."
# adventurer_join_pref: "Either get together with (or recruit!) an Artisan and work with them, or check the box below to receive emails when there are new levels to test. We'll also be posting about levels to review on our networks like"
# adventurer_forum_url: "our forum"
# adventurer_join_suf: "so if you prefer to be notified those ways, sign up there!"
# more_about_adventurer: "Learn More About Becoming A Brave Adventurer"
# more_about_adventurer: "Learn More About Becoming an Adventurer"
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
# scribe_introduction_pref: "CodeCombat isn't just going to be a bunch of levels. It will also include a resource for knowledge, a wiki of programming concepts that levels can hook into. That way rather than each Artisan having to describe in detail what a comparison operator is, they can simply link their level to the Article describing them that is already written for the player's edification. Something along the lines of what the "
# scribe_introduction_url_mozilla: "Mozilla Developer Network"
# scribe_introduction_suf: " has built. If your idea of fun is articulating the concepts of programming in Markdown form, then this class might be for you."
# scribe_attribute_1: "Skill in words is pretty much all you need. Not only grammar and spelling, but able to convey complicated ideas to others."
# contact_us_url: "Contact us"
# scribe_join_description: "tell us a little about yourself, your experience with programming and what sort of things you'd like to write about. We'll go from there!"
# more_about_scribe: "Learn More About Becoming A Diligent Scribe"
# more_about_scribe: "Learn More About Becoming a Scribe"
# scribe_subscribe_desc: "Get emails about article writing announcements."
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
# diplomat_introduction_pref: "So, if there's one thing we learned from the "
# diplomat_launch_url: "launch in October"
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries, particularly Brazil! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_attribute_1: "Fluency in English and the language you would like to translate to. When conveying complicated ideas, it's important to have a strong grasp in both!"
# diplomat_join_pref: "We've started a lot of initial translations at "
# diplomat_doc_url: "this forum post"
# diplomat_join_suf: "so check it out and add things for your language. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming A Great Diplomat"
# diplomat_join_pref_github: "Find your language locale file "
# diplomat_github_url: "on GitHub"
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming a Diplomat"
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
# ambassador_introduction: "This is a community we're building, and you are the connections. We've got Olark chats, emails, and social networks with lots of people to talk with and help get acquainted with the game and learn from. If you want to help people get involved and have fun, and get a good feel of the pulse of CodeCombat and where we're going, then this class might be for you."
# ambassador_attribute_1: "Communication skills. Be able to identify the problems players are having and help them solve them. Also, keep the rest of us informed about what players are saying, what they like and don't like and want more of!"
# ambassador_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll go from there!"
# ambassador_join_note_strong: "Note"
# ambassador_join_note_desc: "One of our top priorities is to build multiplayer where players having difficulty solving levels can summon higher level wizards to help them. This will be a great way for ambassadors to do their thing. We'll keep you posted!"
# more_about_ambassador: "Learn More About Becoming A Helpful Ambassador"
# more_about_ambassador: "Learn More About Becoming an Ambassador"
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
# counselor_introduction_1: "Do you have life experience? A different perspective on things that can help us decide how to shape CodeCombat? Of all these roles, this will probably take the least time, but individually you may make the most difference. We're on the lookout for wisened sages, particularly in areas like: teaching, game development, open source project management, technical recruiting, entrepreneurship, or design."
# counselor_introduction_2: "Or really anything that is relevant to the development of CodeCombat. If you have knowledge and want to share it to help grow this project, then this class might be for you."
# counselor_attribute_1: "Experience, in any of the areas above or something you think might be helpful."
# counselor_attribute_2: "A little bit of free time!"
# counselor_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll put you in our contact list and be in touch when we could use advice (not too often)."
# more_about_counselor: "Learn More About Becoming A Valuable Counselor"
# more_about_counselor: "Learn More About Becoming a Counselor"
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
# diligent_scribes: "Our Diligent Scribes:"
# powerful_archmages: "Our Powerful Archmages:"

View file

@ -104,6 +104,14 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
wizard_settings:
title: "Ajustes del mago"
customize_avatar: "Personaliza tu Avatar"
clothes: "Ropa"
# trim: "Trim"
cloud: "Nube"
# spell: "Spell"
boots: "Botas"
# hue: "Hue"
# saturation: "Saturation"
# lightness: "Lightness"
account_settings:
title: "Ajustes de la cuenta"
@ -150,7 +158,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
gravatar_profile_link: "Perfil de Gravatar completo"
play_level:
level_load_error: "No se pudo cargar el nivel."
level_load_error: "No se pudo cargar el nivel: "
done: "Hecho"
grid: "Cuadrícrula"
customize_wizard: "Personalizar Mago"
@ -194,14 +202,14 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
spell_saved: "Hechizo guardado"
# admin:
av_title: "Vista de Administrador"
# av_title: "Admin Views"
av_entities_sub_title: "Entidades"
av_entities_users_url: "Usuarios"
av_entities_active_instances_url: "Instancias Activas"
av_other_sub_title: "Otras"
av_other_debug_base_url: "Base (para depurar base.jade)"
u_title: "Lista de Usuario"
lg_title: "Últimos juegos"
av_other_sub_title: "Otros"
# av_other_debug_base_url: "Base (for debugging base.jade)"
u_title: "Lista de Usuarios"
lg_title: "Últimos Juegos"
editor:
main_title: "Editores de CodeCombat"
@ -245,7 +253,6 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
general:
and: "y"
or: "o"
name: "Nombre"
body: "Cuerpo"
version: "Versión"
@ -253,6 +260,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
version_history_for: "Historial de las versiones de: "
results: "Resultados"
description: "Descripción"
or: "o"
email: "Correo electrónico"
message: "Mensaje"
@ -352,6 +360,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
alert_account_message_pref: "Para suscribirte a los correos electrónicos de las distintas Clases, necesitarás "
alert_account_message_suf: "primero."
alert_account_message_create_url: "crear una cuenta"
# archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
archmage_introduction: "Una de las mejores partes de desarrollar juegos es que combinan cosas muy diferentes. Gráficos, sonido, uso de redes en tiempo real, redes sociales y por supuesto mucho de los aspectos comunes de la programación, desde gestión de bases de datos a bajo nivel y administración de servidores hasta diseño de experiencia del usuario y creación de interfaces. Hay un montón de cosas por hacer y si eres un programador experimentado con interés en conocer lo que se cuece en la trastienda de CodeCombat, esta Clase puede ser la ideal para ti. Nos encantaría recibir tu ayuda para crear el mejor juego de programación de la historia."
class_attributes: "Atributos de las Clases"
archmage_attribute_1_pref: "Conocimiento en "
@ -366,6 +375,8 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
join_url_hipchat: "sala pública en HipChat"
more_about_archmage: "Aprende más sobre convertirte en un poderoso Archimago"
archmage_subscribe_desc: "Recibe correos sobre nuevos anuncios y oportunidades de codificar."
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
artisan_summary_suf: "entonces esta Clase es la tuya."
artisan_introduction_pref: "¡Debemos construir niveles adicionales! La gente clama por más contenido y solo podemos crear unos cuantos. Ahora mismo tu estación de trabajo es el nivel uno; nuestro editor de niveles es apenas usable por sus creadores, así que ten cuidado. Si tienes visiones de campañas que alcanzan el infinito"
artisan_introduction_suf: "entonces esta Clase es ideal para ti."
artisan_attribute_1: "Cualquier experiencia creando contenido similar estaría bien, como por ejemplo el editor de niveles de Blizzard. ¡Aunque no es necesaria!"
@ -378,6 +389,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
artisan_join_step4: "Publica tus niveles en el foro para recibir comentarios críticos."
more_about_artisan: "Aprende más sobre convertirte en un Artesano creativo"
artisan_subscribe_desc: "Recibe correos sobre actualizaciones del editor de niveles y anuncios."
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class is for you."
adventurer_introduction: "Hablemos claro sobre tu papel: eres el tanque. Vas a recibir fuertes daños. Necesitamos gente para probar nuestros flamantes niveles y ayudar a mejorarlos. El dolor será enorme; hacer buenos juegos es un proceso largo y nadie lo consigue a la primera. Si puedes resistir y tener una puntuación alta en Resistencia, entonces esta Clase es para ti."
adventurer_attribute_1: "Estar sediento de conocimientos. Quieres aprender a programar y nosotros queremos enseñarte cómo hacerlo. Aunque en este caso es más probable que seas tú el que esté haciendo la mayor parte de la enseñanza."
adventurer_attribute_2: "Carismático. Se amable pero claro a la hora de desglosar qué necesita ser mejorado y sugiere de qué formas podría hacerse."
@ -386,6 +398,8 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
adventurer_join_suf: "así que si prefieres estar informado en esa forma, ¡crea una cuenta allí!"
more_about_adventurer: "Aprende más sobre cómo convertirte en un bravo Aventurero"
adventurer_subscribe_desc: "Recibe correos cuando haya nuevos niveles para testar."
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
scribe_introduction_pref: "CodeCombat no será solo un montón de niveles. También será una fuente de conocimientos, una wiki de conceptos de programación a la que los niveles se engancharan. De esa forma, en lugar de que cada Artesano tenga que describir en detalle qué es un operador de comparación, podrá simplemente enlazar el nivel al Artículo que los describe y que ya ha sido escrito para edificación del jugador. Algo en la línea de lo que la "
scribe_introduction_url_mozilla: "Mozilla Developer Network"
scribe_introduction_suf: " ha construido. Si tu idea de diversión es articular los conceptos de la programación de una forma sencilla, entonces esta clase es para ti."
@ -394,15 +408,17 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
scribe_join_description: "cuéntanos más sobre ti, tu experiencia en el mundo de la programación y sobre qué cosas te gustaría escribir. ¡Y continuaremos a partir de ahí!"
more_about_scribe: "Aprende más sobre convertirte en un Escriba diligente"
scribe_subscribe_desc: "Recibe correos sobre anuncios de redacción de Artículos."
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
diplomat_introduction_pref: "Así, si hemos aprendido algo desde el "
diplomat_launch_url: "lanzamiento en octubre"
diplomat_introduction_suf: "hay un interés considerable en CodeCombat en otros paises, ¡especialmente Brasil! Estamos formando un cuerpo de traductores con ganas de traducir un grupo de palabras tras otro para hacer CodeCombat tan accesible para todo el mundo como sea posible. Si quieres recibir avances de próximos contenidos y quieres poner esos niveles a disposición de los que comparten tu idioma tan pronto como sea posible, entonces esta Clase es para ti."
diplomat_attribute_1: "Fluidez con el ingles y el lenguaje al que quieras traducir. Cuando de transmitir ideas complejas se trata, ¡es importante tener grandes conocimientos de ambas!"
diplomat_join_pref: "Hemos comenzado un montón de traducciones en "
diplomat_doc_url: "este post del foro"
diplomat_join_suf: "así que échale un vistazo y añade cosas para tu idioma. También, marca la casilla de abajo para mantenerte al día en nuevos desarrollos de internacionalización!"
diplomat_join_pref_github: "Encuentra el fichero local de tu idioma "
diplomat_github_url: "en GitHub"
diplomat_join_suf_github: ", edítalo online, y solicita que sea revisado. Además, marca la casilla de abajo para mantenerte informado en nuevos progresos en Internacionalización."
more_about_diplomat: "Aprende más sobre cómo convertirte en un gran Diplomático"
diplomat_subscribe_desc: "Recibe correos sobre nuevos niveles y desarrollos para traducir."
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
ambassador_introduction: "Esta es una comunidad en construcción y tú eres parte de las conexiones. Tenemos chat Olark, correos electrónicos y las redes sociales con una gran cantidad de personas con quienes hablar, ayudar a familiarizarse con el juego y aprender. Si quieres ayudar a la gente a que se involucre, se divierta, y tenga buenas sensaciones sobre CodeCombat y hacia dónde vamos, entonces esta clase es para ti."
ambassador_attribute_1: "Habilidades de comunicación. Ser capaz de identificar los problemas que los jugadores están teniendo y ayudarles a resolverlos. Además, mantener al resto de nosotros informados sobre lo que los jugadores están diciendo, lo que les gusta, lo que no ¡y de lo que quieren más!"
ambassador_join_desc: "cuéntanos más sobre ti, que has hecho y qué estarías interesado en hacer. ¡Y continuaremos a partir de ahí!"
@ -410,6 +426,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
ambassador_join_note_desc: "Una de nuestras principales prioridades es construir un modo multijugador donde los jugadores con mayores dificultades a la hora de resolver un nivel, puedan invocar a los magos más avanzados para que les ayuden. Será una buena manera de que los Embajadores puedan hacer su trabajo. ¡Te mantendremos informado!"
more_about_ambassador: "Aprende más sobre cómo convertirte en un amable Embajador"
ambassador_subscribe_desc: "Recibe correos sobre actualizaciones de soporte y desarrollo del multijugador."
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
counselor_introduction_1: "¿Tienes mucha experiencia vital? ¿Una perspectiva diferente de las cosas que nos puede ayudar a decidir cómo moldear CodeCombat? De todos estos papeles, este es el que te llevará menos tiempo pero en el que marcarás más la diferencia. Estamos buscando eruditos particularmente en áreas como: enseñanza, desarrollo de juegos, gestión de proyectos de código abierto, contratación de técnicos, iniciativa empresarial o diseño."
counselor_introduction_2: "O realmente cualquier cosa que sea relevante para el desarrollo de CodeCombat. Si tienes el conocimiento y quieres compartirlo para ayudar a que este proyecto crezca, entonces esta Clase es ideal para ti."
counselor_attribute_1: "Experiencia en cualquiera de las áreas mencionadas, o en lo que creas que puede ser de utilidad."

View file

@ -4,7 +4,7 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
saving: "Guardando..."
sending: "Enviando..."
cancel: "Cancelar"
# save: "Save"
# save: "Guardar"
delay_1_sec: "1 segundo"
delay_3_sec: "3 segundos"
delay_5_sec: "5 segundos"
@ -31,15 +31,15 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
about: "Sobre"
contact: "Contacto"
twitter_follow: "Seguir"
# employers: "Employers"
# employers: "Empleados"
# versions:
# save_version_title: "Save New Version"
# save_version_title: "Guardar Nueva Versión"
# new_major_version: "New Major Version"
# cla_prefix: "To save changes, first you must agree to our"
# cla_prefix: "Para poder guardar los cambios, primero debes aceptar nuestra"
# cla_url: "CLA"
# cla_suffix: "."
# cla_agree: "I AGREE"
# cla_agree: "ACEPTO"
login:
sign_up: "Crear Cuenta"
@ -48,11 +48,11 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
recover: "recuperar cuenta"
# recover:
# recover_account_title: "Recover Account"
# send_password: "Send Recovery Password"
# recover_account_title: "Recuperar cuenta"
# send_password: "Enviar contraseña olvidada"
signup:
# create_account_title: "Create Account to Save Progress"
# create_account_title: "Crea una cuenta para guardar el progreso"
description: "Es gratis. Solo necesitas un par de cosas y estarás listo para comenzar:"
email_announcements: "Recibe noticias por email"
coppa: "más de 13 años o fuera de los Estados Unidos"
@ -102,13 +102,21 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
subscribe_as_diplomat: "Suscribete como un Diplomático"
# wizard_settings:
# title: "Wizard Settings"
# customize_avatar: "Customize Your Avatar"
# title: "Configuración del mago"
# customize_avatar: "Personaliza tu avatar"
# clothes: "Ropa"
# trim: "Trim"
# cloud: "Nube"
# spell: "Spell"
# boots: "Botas"
# hue: "Hue"
# saturation: "Saturación"
# lightness: "Brillo"
account_settings:
title: "Configuración de la Cuenta"
not_logged_in: "Inicia sesión o crea una cuenta para cambiar tu configuración."
autosave: "Cambios Guardados Automáticamente"
autosave: "Los cambios se guardan Automáticamente"
me_tab: "Yo"
picture_tab: "Imagen"
wizard_tab: "Hechicero"
@ -131,7 +139,7 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
email_toggle: "Activar todo"
error_saving: "Error al guardar"
saved: "Cambios guardados"
password_mismatch: "El password no coincide"
password_mismatch: "La contraseña no coincide"
account_profile:
edit_settings: "Editar Ajustes"
@ -150,7 +158,7 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
gravatar_profile_link: "Prefil de Gravatar completo"
play_level:
level_load_error: "No se pudo cargar el nivel."
level_load_error: "No se pudo cargar el nivel: "
done: "Hecho"
grid: "Cuadrícrula"
customize_wizard: "Personalizar Mago"
@ -225,7 +233,7 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
# level_tab_thangs_title: "Current Thangs"
# level_tab_thangs_conditions: "Starting Conditions"
# level_tab_thangs_add: "Add Thangs"
# level_settings_title: "Settings"
# level_settings_title: "Ajustes"
# level_component_tab_title: "Current Components"
# level_component_btn_new: "Create New Component"
# level_systems_tab_title: "Current Systems"
@ -245,7 +253,6 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
general:
# and: "and"
or: "o"
name: "Nombre"
# body: "Body"
# version: "Version"
@ -253,6 +260,7 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
# version_history_for: "Version History for: "
# results: "Results"
# description: "Description"
or: "o"
email: "Email"
message: "Mensaje"
@ -352,6 +360,7 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
# alert_account_message_pref: "To subscribe for class emails, you'll need to "
# alert_account_message_suf: "first."
# alert_account_message_create_url: "create an account"
# archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
# archmage_introduction: "One of the best parts about building games is they synthesize so many different things. Graphics, sound, real-time networking, social networking, and of course many of the more common aspects of programming, from low-level database management, and server administration to user facing design and interface building. There's a lot to do, and if you're an experienced programmer with a hankering to really dive into the nitty-gritty of CodeCombat, this class might be for you. We would love to have your help building the best programming game ever."
# class_attributes: "Class Attributes"
# archmage_attribute_1_pref: "Knowledge in "
@ -364,10 +373,12 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
# join_desc_4: "and we'll go from there!"
# join_url_email: "Email us"
# join_url_hipchat: "public HipChat room"
# more_about_archmage: "Learn More About Becoming A Powerful Archmage"
# more_about_archmage: "Learn More About Becoming an Archmage"
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
# artisan_summary_suf: "then this class is for you."
# artisan_introduction_pref: "We must construct additional levels! People be clamoring for more content, and we can only build so many ourselves. Right now your workstation is level one; our level editor is barely usable even by its creators, so be wary. If you have visions of campaigns spanning for-loops to"
# artisan_introduction_suf: "to then this class might be for you."
# artisan_introduction_suf: "then this class might be for you."
# artisan_attribute_1: "Any experience in building content like this would be nice, such as using Blizzard's level editors. But not required!"
# artisan_attribute_2: "A hankering to do a whole lot of testing and iteration. To make good levels, you need to take it to others and watch them play it, and be prepared to find a lot of things to fix."
# artisan_attribute_3: "For the time being, endurance en par with an Adventurer. Our Level Editor is super preliminary and frustrating to use. You have been warned!"
@ -376,46 +387,52 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
# artisan_join_step2: "Create a new level and explore existing levels."
# artisan_join_step3: "Find us in our public HipChat room for help."
# artisan_join_step4: "Post your levels on the forum for feedback."
# more_about_artisan: "Learn More About Becoming A Creative Artisan"
# more_about_artisan: "Learn More About Becoming an Artisan"
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class is for you."
# adventurer_introduction: "Let's be clear about your role: you are the tank. You're going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class might be for you."
# adventurer_attribute_1: "A thirst for learning. You want to learn how to code and we want to teach you how to code. You'll probably be doing most of the teaching in this case, though."
# adventurer_attribute_2: "Charismatic. Be gentle but articulate about what needs improving, and offer suggestions on how to improve."
# adventurer_join_pref: "Either get together with (or recruit!) an Artisan and work with them, or check the box below to receive emails when there are new levels to test. We'll also be posting about levels to review on our networks like"
# adventurer_forum_url: "our forum"
# adventurer_join_suf: "so if you prefer to be notified those ways, sign up there!"
# more_about_adventurer: "Learn More About Becoming A Brave Adventurer"
# more_about_adventurer: "Learn More About Becoming an Adventurer"
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
# scribe_introduction_pref: "CodeCombat isn't just going to be a bunch of levels. It will also include a resource for knowledge, a wiki of programming concepts that levels can hook into. That way rather than each Artisan having to describe in detail what a comparison operator is, they can simply link their level to the Article describing them that is already written for the player's edification. Something along the lines of what the "
# scribe_introduction_url_mozilla: "Mozilla Developer Network"
# scribe_introduction_suf: " has built. If your idea of fun is articulating the concepts of programming in Markdown form, then this class might be for you."
# scribe_attribute_1: "Skill in words is pretty much all you need. Not only grammar and spelling, but able to convey complicated ideas to others."
# contact_us_url: "Contact us"
# scribe_join_description: "tell us a little about yourself, your experience with programming and what sort of things you'd like to write about. We'll go from there!"
# more_about_scribe: "Learn More About Becoming A Diligent Scribe"
# more_about_scribe: "Learn More About Becoming a Scribe"
# scribe_subscribe_desc: "Get emails about article writing announcements."
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
# diplomat_introduction_pref: "So, if there's one thing we learned from the "
# diplomat_launch_url: "launch in October"
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries, particularly Brazil! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_attribute_1: "Fluency in English and the language you would like to translate to. When conveying complicated ideas, it's important to have a strong grasp in both!"
# diplomat_join_pref: "We've started a lot of initial translations at "
# diplomat_doc_url: "this forum post"
# diplomat_join_suf: "so check it out and add things for your language. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming A Great Diplomat"
# diplomat_join_pref_github: "Find your language locale file "
# diplomat_github_url: "on GitHub"
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming a Diplomat"
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
# ambassador_introduction: "This is a community we're building, and you are the connections. We've got Olark chats, emails, and social networks with lots of people to talk with and help get acquainted with the game and learn from. If you want to help people get involved and have fun, and get a good feel of the pulse of CodeCombat and where we're going, then this class might be for you."
# ambassador_attribute_1: "Communication skills. Be able to identify the problems players are having and help them solve them. Also, keep the rest of us informed about what players are saying, what they like and don't like and want more of!"
# ambassador_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll go from there!"
# ambassador_join_note_strong: "Note"
# ambassador_join_note_desc: "One of our top priorities is to build multiplayer where players having difficulty solving levels can summon higher level wizards to help them. This will be a great way for ambassadors to do their thing. We'll keep you posted!"
# more_about_ambassador: "Learn More About Becoming A Helpful Ambassador"
# more_about_ambassador: "Learn More About Becoming an Ambassador"
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
# counselor_introduction_1: "Do you have life experience? A different perspective on things that can help us decide how to shape CodeCombat? Of all these roles, this will probably take the least time, but individually you may make the most difference. We're on the lookout for wisened sages, particularly in areas like: teaching, game development, open source project management, technical recruiting, entrepreneurship, or design."
# counselor_introduction_2: "Or really anything that is relevant to the development of CodeCombat. If you have knowledge and want to share it to help grow this project, then this class might be for you."
# counselor_attribute_1: "Experience, in any of the areas above or something you think might be helpful."
# counselor_attribute_2: "A little bit of free time!"
# counselor_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll put you in our contact list and be in touch when we could use advice (not too often)."
# more_about_counselor: "Learn More About Becoming A Valuable Counselor"
# more_about_counselor: "Learn More About Becoming a Counselor"
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
# diligent_scribes: "Our Diligent Scribes:"
# powerful_archmages: "Our Powerful Archmages:"

View file

@ -5,10 +5,10 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
sending: "...در حال ارسال"
cancel: "لغو"
save: "ذخیره "
# delay_1_sec: "1 second"
# delay_3_sec: "3 seconds"
# delay_5_sec: "5 seconds"
# manual: "Manual"
delay_1_sec: "1 ثانیه"
delay_3_sec: "3 ثانیه"
delay_5_sec: "5 ثانیه"
manual: "دستی"
# fork: "Fork"
play: "سطوح"
@ -75,47 +75,55 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
campaign_beginner: "کمپین تازه کارها"
campaign_beginner_description: ".که شما در آن می توانید جادوگری به وسیله برنامه نویسی را یادبگیرید..."
campaign_dev: "مراحل سخت تصادفی"
# campaign_dev_description: "... in which you learn the interface while doing something a little harder."
campaign_dev_description: "... جایی که میتونید طراحی ظاهر رو یاد بگیرید درحالی که فعالیت سخت تری انجام میدید"
campaign_multiplayer: "مسابقات چند نفره"
# campaign_multiplayer_description: "... in which you code head-to-head against other players."
campaign_multiplayer_description: "... جایی که کد رو به رو شدن با بقیه بازیکنان رو مینویسید."
campaign_player_created: "ایجاد بازیکن"
# campaign_player_created_description: "... in which you battle against the creativity of your fellow <a href=\"/contribute#artisan\">Artisan Wizards</a>."
# level_difficulty: "Difficulty: "
campaign_player_created_description: "... جایی که در مقابل خلاقیت نیرو هاتون قرار میگیرید <a href=\"/contribute#artisan\">جادوگران آرتیزان</a>."
level_difficulty: "سختی: "
contact:
contact_us: "CodeCombatتماس با "
welcome: "خوب است از شما بشنویم, از طریق این فرم برای ما ایمیل ارسال کنید"
# contribute_prefix: "If you're interested in contributing, check out our "
# contribute_page: "contribute page"
# contribute_suffix: "!"
# forum_prefix: "For anything public, please try "
# forum_page: "our forum"
# forum_suffix: " instead."
# send: "Send Feedback"
contribute_prefix: "اگر علاقه مند به همکاری با ما هستید ، این صفحه را مطالعه کنید"
contribute_page: "صفحه همکاری"
contribute_suffix: "!"
forum_prefix: "باری هر چیز عمومی، اینجا را مشاهده کنید "
forum_page: "فاروم ما"
forum_suffix: " به جای"
send: "ارسال بازخورد"
diplomat_suggestion:
# title: "Help translate CodeCombat!"
# sub_heading: "We need your language skills."
pitch_body: "We develop CodeCombat in English, but we already have players all over the world. Many of them want to play in Persian but don't speak English, so if you can speak both, please consider signing up to be a Diplomat and help translate both the CodeCombat website and all the levels into Persian."
missing_translations: "Until we can translate everything into Persian, you'll see English when Persian isn't available."
# learn_more: "Learn more about being a Diplomat"
# subscribe_as_diplomat: "Subscribe as a Diplomat"
title: "کمک به ترجمه کمبت کد!"
sub_heading: "ما توانایی زبان شما را نیاز داریم"
pitch_body: "ما کمبت کد را به زبان انگلیسی توسعه داده ایم اما بازیکنانی از سراسر دنیا داریم. خیلی از آنها دوست داند به فارسی بازیکنند اما انگلیسی صحبت نکنند, پس اگر به هر دو زبان میتوانید صحبت کنید, پس لطفاً به عنوان دیپلمات ثبت نامکنید و مارا در ترجمه بازی و تمام مراحل به فارسی یاری نمایید."
missing_translations: "تا زمانی که به مشغول ترجمه به فارسی هستیم , شما انگلیسی مشاهده میکنید بدون ترجمه فارسی."
learn_more: "بیشتر درباره دیپلمات بودن بیاموزید"
subscribe_as_diplomat: "به عنوان یک دیپلمات تعقیبمان کنید"
# wizard_settings:
# title: "Wizard Settings"
# customize_avatar: "Customize Your Avatar"
wizard_settings:
title: "تنظیمات جادویی"
customize_avatar: "آواتار خود را شکل دهید"
# clothes: "Clothes"
# trim: "Trim"
# cloud: "Cloud"
# spell: "Spell"
# boots: "Boots"
# hue: "Hue"
# saturation: "Saturation"
# lightness: "Lightness"
# account_settings:
# title: "Account Settings"
# not_logged_in: "Log in or create an account to change your settings."
# autosave: "Changes Save Automatically"
# me_tab: "Me"
# picture_tab: "Picture"
# wizard_tab: "Wizard"
# password_tab: "Password"
# emails_tab: "Emails"
# gravatar_select: "Select which Gravatar photo to use"
# gravatar_add_photos: "Add thumbnails and photos to a Gravatar account for your email to choose an image."
account_settings:
title: "تنظیمات حساب کاربری"
not_logged_in: "برای ایجاد تغییر وارد شوید یا ثبت نام نمایید"
autosave: "تغییرات به طور خودکار ثبت شد"
me_tab: "من"
picture_tab: "تصاویر"
wizard_tab: "جادو"
password_tab: "کلمه عبور"
emails_tab: "ایمیل ها"
gravatar_select: " استفاده شود Gravatar انتخاب کنید کدام تصویر"
gravatar_add_photos: "Add thumbnails and photos to a Gravatar account for your email to choose an image."
# gravatar_add_more_photos: "Add more photos to your Gravatar account to access them here."
# wizard_color: "Wizard Clothes Color"
# new_password: "New Password"
@ -150,7 +158,7 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
# gravatar_profile_link: "Full Gravatar Profile"
# play_level:
# level_load_error: "Level could not be loaded."
# level_load_error: "Level could not be loaded: "
# done: "Done"
# grid: "Grid"
# customize_wizard: "Customize Wizard"
@ -173,7 +181,7 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
# victory_go_home: "Go Home"
# victory_review: "Tell us more!"
# victory_hour_of_code_done: "Are You Done?"
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
# multiplayer_title: "Multiplayer Settings"
# multiplayer_link_description: "Give this link to anyone to have them join you."
# multiplayer_hint_label: "Hint:"
@ -183,7 +191,7 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
# tome_minion_spells: "Your Minions' Spells"
# tome_read_only_spells: "Read-Only Spells"
# tome_other_units: "Other Units"
# tome_cast_button_castable: "Cast"
# tome_cast_button_castable: "Cast Spell"
# tome_cast_button_casting: "Casting"
# tome_cast_button_cast: "Spell Cast"
# tome_autocast_delay: "Autocast Delay"
@ -245,7 +253,6 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
general:
# and: "and"
or: "یا"
name: "نام"
# body: "Body"
# version: "Version"
@ -253,6 +260,7 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
# version_history_for: "Version History for: "
# results: "Results"
# description: "Description"
or: "یا"
email: "ایمیل"
message: "پیام"
@ -352,6 +360,7 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
# alert_account_message_pref: "To subscribe for class emails, you'll need to "
# alert_account_message_suf: "first."
# alert_account_message_create_url: "create an account"
# archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
# archmage_introduction: "One of the best parts about building games is they synthesize so many different things. Graphics, sound, real-time networking, social networking, and of course many of the more common aspects of programming, from low-level database management, and server administration to user facing design and interface building. There's a lot to do, and if you're an experienced programmer with a hankering to really dive into the nitty-gritty of CodeCombat, this class might be for you. We would love to have your help building the best programming game ever."
# class_attributes: "Class Attributes"
# archmage_attribute_1_pref: "Knowledge in "
@ -364,10 +373,12 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
# join_desc_4: "and we'll go from there!"
# join_url_email: "Email us"
# join_url_hipchat: "public HipChat room"
# more_about_archmage: "Learn More About Becoming A Powerful Archmage"
# more_about_archmage: "Learn More About Becoming an Archmage"
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
# artisan_summary_suf: "then this class is for you."
# artisan_introduction_pref: "We must construct additional levels! People be clamoring for more content, and we can only build so many ourselves. Right now your workstation is level one; our level editor is barely usable even by its creators, so be wary. If you have visions of campaigns spanning for-loops to"
# artisan_introduction_suf: "to then this class might be for you."
# artisan_introduction_suf: "then this class might be for you."
# artisan_attribute_1: "Any experience in building content like this would be nice, such as using Blizzard's level editors. But not required!"
# artisan_attribute_2: "A hankering to do a whole lot of testing and iteration. To make good levels, you need to take it to others and watch them play it, and be prepared to find a lot of things to fix."
# artisan_attribute_3: "For the time being, endurance en par with an Adventurer. Our Level Editor is super preliminary and frustrating to use. You have been warned!"
@ -376,46 +387,52 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
# artisan_join_step2: "Create a new level and explore existing levels."
# artisan_join_step3: "Find us in our public HipChat room for help."
# artisan_join_step4: "Post your levels on the forum for feedback."
# more_about_artisan: "Learn More About Becoming A Creative Artisan"
# more_about_artisan: "Learn More About Becoming an Artisan"
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class is for you."
# adventurer_introduction: "Let's be clear about your role: you are the tank. You're going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class might be for you."
# adventurer_attribute_1: "A thirst for learning. You want to learn how to code and we want to teach you how to code. You'll probably be doing most of the teaching in this case, though."
# adventurer_attribute_2: "Charismatic. Be gentle but articulate about what needs improving, and offer suggestions on how to improve."
# adventurer_join_pref: "Either get together with (or recruit!) an Artisan and work with them, or check the box below to receive emails when there are new levels to test. We'll also be posting about levels to review on our networks like"
# adventurer_forum_url: "our forum"
# adventurer_join_suf: "so if you prefer to be notified those ways, sign up there!"
# more_about_adventurer: "Learn More About Becoming A Brave Adventurer"
# more_about_adventurer: "Learn More About Becoming an Adventurer"
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
# scribe_introduction_pref: "CodeCombat isn't just going to be a bunch of levels. It will also include a resource for knowledge, a wiki of programming concepts that levels can hook into. That way rather than each Artisan having to describe in detail what a comparison operator is, they can simply link their level to the Article describing them that is already written for the player's edification. Something along the lines of what the "
# scribe_introduction_url_mozilla: "Mozilla Developer Network"
# scribe_introduction_suf: " has built. If your idea of fun is articulating the concepts of programming in Markdown form, then this class might be for you."
# scribe_attribute_1: "Skill in words is pretty much all you need. Not only grammar and spelling, but able to convey complicated ideas to others."
# contact_us_url: "Contact us"
# scribe_join_description: "tell us a little about yourself, your experience with programming and what sort of things you'd like to write about. We'll go from there!"
# more_about_scribe: "Learn More About Becoming A Diligent Scribe"
# more_about_scribe: "Learn More About Becoming a Scribe"
# scribe_subscribe_desc: "Get emails about article writing announcements."
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
# diplomat_introduction_pref: "So, if there's one thing we learned from the "
# diplomat_launch_url: "launch in October"
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries, particularly Brazil! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
# diplomat_attribute_1: "Fluency in English and the language you would like to translate to. When conveying complicated ideas, it's important to have a strong grasp in both!"
# diplomat_join_pref: "We've started a lot of initial translations at "
# diplomat_doc_url: "this forum post"
# diplomat_join_suf: "so check it out and add things for your language. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming A Great Diplomat"
# diplomat_join_pref_github: "Find your language locale file "
# diplomat_github_url: "on GitHub"
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
# more_about_diplomat: "Learn More About Becoming a Diplomat"
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
# ambassador_introduction: "This is a community we're building, and you are the connections. We've got Olark chats, emails, and social networks with lots of people to talk with and help get acquainted with the game and learn from. If you want to help people get involved and have fun, and get a good feel of the pulse of CodeCombat and where we're going, then this class might be for you."
# ambassador_attribute_1: "Communication skills. Be able to identify the problems players are having and help them solve them. Also, keep the rest of us informed about what players are saying, what they like and don't like and want more of!"
# ambassador_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll go from there!"
# ambassador_join_note_strong: "Note"
# ambassador_join_note_desc: "One of our top priorities is to build multiplayer where players having difficulty solving levels can summon higher level wizards to help them. This will be a great way for ambassadors to do their thing. We'll keep you posted!"
# more_about_ambassador: "Learn More About Becoming A Helpful Ambassador"
# more_about_ambassador: "Learn More About Becoming an Ambassador"
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
# counselor_introduction_1: "Do you have life experience? A different perspective on things that can help us decide how to shape CodeCombat? Of all these roles, this will probably take the least time, but individually you may make the most difference. We're on the lookout for wisened sages, particularly in areas like: teaching, game development, open source project management, technical recruiting, entrepreneurship, or design."
# counselor_introduction_2: "Or really anything that is relevant to the development of CodeCombat. If you have knowledge and want to share it to help grow this project, then this class might be for you."
# counselor_attribute_1: "Experience, in any of the areas above or something you think might be helpful."
# counselor_attribute_2: "A little bit of free time!"
# counselor_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll put you in our contact list and be in touch when we could use advice (not too often)."
# more_about_counselor: "Learn More About Becoming A Valuable Counselor"
# more_about_counselor: "Learn More About Becoming a Counselor"
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
# diligent_scribes: "Our Diligent Scribes:"
# powerful_archmages: "Our Powerful Archmages:"

Some files were not shown because too many files have changed in this diff Show more