Preserving flag history and submission count so that things are more stable in between real-time submissions.

This commit is contained in:
Nick Winter 2014-10-18 17:32:01 -07:00
parent 9ce8ebaf25
commit 24da2aa80a
9 changed files with 62 additions and 8 deletions

View file

@ -290,6 +290,8 @@ self.setupDebugWorldToRunUntilFrame = function (args) {
try {
self.debugWorld = new World(args.userCodeMap);
self.debugWorld.levelSessionIDs = args.levelSessionIDs;
self.debugWorld.submissionCount = args.submissionCount;
self.debugWorld.flagHistory = args.flagHistory;
if (args.level)
self.debugWorld.loadFromLevel(args.level, true);
self.debugWorld.debugging = true;
@ -347,6 +349,8 @@ self.runWorld = function runWorld(args) {
try {
self.world = new World(args.userCodeMap);
self.world.levelSessionIDs = args.levelSessionIDs;
self.world.submissionCount = args.submissionCount;
self.world.flagHistory = args.flagHistory || [];
if(args.level)
self.world.loadFromLevel(args.level, true);
self.world.preloading = args.preload;

View file

@ -54,9 +54,11 @@ module.exports = class God extends CocoClass
setWorldClassMap: (worldClassMap) -> @angelsShare.worldClassMap = worldClassMap
onTomeCast: (e) ->
@lastSubmissionCount = e.submissionCount
@lastFlagHistory = e.flagHistory
@createWorld e.spells, e.preload, e.realTime
createWorld: (spells, preload=false, realTime=false) ->
createWorld: (spells, preload, realTime) ->
console.log "#{@nick}: Let there be light upon #{@level.name}! (preload: #{preload})"
userCodeMap = @getUserCodeMap spells
@ -81,6 +83,8 @@ module.exports = class God extends CocoClass
userCodeMap: userCodeMap
level: @level
levelSessionIDs: @levelSessionIDs
submissionCount: @lastSubmissionCount
flagHistory: @lastFlagHistory
goals: @angelsShare.goalManager?.getGoals()
headless: @angelsShare.headless
preload: preload
@ -110,6 +114,8 @@ module.exports = class God extends CocoClass
userCodeMap: @currentUserCodeMap
level: @level
levelSessionIDs: @levelSessionIDs
submissionCount: @lastSubmissionCount
flagHistory: @lastFlagHistory
goals: @goalManager?.getGoals()
frame: args.frame
currentThangID: args.thangID

View file

@ -23,8 +23,10 @@ module.exports = class LevelBus extends Bus
'level:show-victory': 'onVictory'
'tome:spell-changed': 'onSpellChanged'
'tome:spell-created': 'onSpellCreated'
'tome:cast-spells': 'onCastSpells'
'application:idle-changed': 'onIdleChanged'
'goal-manager:new-goal-states': 'onNewGoalStates'
'god:new-world-created': 'onNewWorldCreated'
constructor: ->
super(arguments...)
@ -126,6 +128,22 @@ module.exports = class LevelBus extends Bus
# https://github.com/codecombat/codecombat/issues/81
@onSpellChanged e # Save the new spell to the session, too.
onCastSpells: (e) ->
return unless @onPoint() and e.realTime
# We have incremented state.submissionCount and reset state.flagHistory.
@changedSessionProperties.state = true
@saveSession()
onNewWorldCreated: (e) ->
return unless @onPoint()
# Record the flag history.
state = @session.get('state')
return if _.isEqual state.flagHistory, e.world.flagHistory
state.flagHistory = e.world.flagHistory
@changedSessionProperties.state = true
@session.set('state', state)
@saveSession()
onScriptStateChanged: (e) ->
return unless @onPoint()
@fireScriptsRef?.update(e)

View file

@ -334,6 +334,8 @@ module.exports = class LevelLoader extends CocoClass
@initialized = true
@world = new World()
@world.levelSessionIDs = if @opponentSessionID then [@sessionID, @opponentSessionID] else [@sessionID]
@world.submissionCount = @session?.get('state')?.submissionCount ? 0
@world.flagHistory = @session?.get('state')?.flagHistory ? []
serializedLevel = @level.serialize(@supermodel, @session, @opponentSession)
@world.loadFromLevel serializedLevel, false
console.log 'World has been initialized from level loader.'

View file

@ -39,7 +39,6 @@ module.exports = class World
@systems = []
@systemMap = {}
@scriptNotes = []
@flagHistory = []
@rand = new Rand 0 # Existence System may change this seed
@frames = [new WorldFrame(@, 0)]
@ -349,7 +348,8 @@ module.exports = class World
endFrame = @frames.length
#console.log "... world serializing frames from", startFrame, "to", endFrame, "of", @totalFrames
[transferableObjects, nontransferableObjects] = [0, 0]
o = {totalFrames: @totalFrames, maxTotalFrames: @maxTotalFrames, frameRate: @frameRate, dt: @dt, victory: @victory, userCodeMap: {}, trackedProperties: {}}
delete flag.processed for flag in @flagHistory
o = {totalFrames: @totalFrames, maxTotalFrames: @maxTotalFrames, frameRate: @frameRate, dt: @dt, victory: @victory, userCodeMap: {}, trackedProperties: {}, flagHistory: @flagHistory}
o.trackedProperties[prop] = @[prop] for prop in @trackedProperties or []
for thangID, methods of @userCodeMap
@ -455,7 +455,7 @@ module.exports = class World
w.userCodeMap[thangID][methodName][aetherStateKey] = serializedAether[aetherStateKey]
else
w = new World o.userCodeMap, classMap
[w.totalFrames, w.maxTotalFrames, w.frameRate, w.dt, w.scriptNotes, w.victory] = [o.totalFrames, o.maxTotalFrames, o.frameRate, o.dt, o.scriptNotes ? [], o.victory]
[w.totalFrames, w.maxTotalFrames, w.frameRate, w.dt, w.scriptNotes, w.victory, w.flagHistory] = [o.totalFrames, o.maxTotalFrames, o.frameRate, o.dt, o.scriptNotes ? [], o.victory, o.flagHistory]
w[prop] = val for prop, val of o.trackedProperties
perf.t1 = now()

View file

@ -110,6 +110,22 @@ _.extend LevelSessionSchema.properties,
type: 'object'
properties:
status: enum: ['failure', 'incomplete', 'success']
submissionCount:
description: 'How many times the session has been submitted for real-time playback (can affect the random seed).'
type: 'integer'
minimum: 0
flagHistory:
description: 'The history of flag events during the last real-time playback submission.'
type: 'array'
items: c.object {required: ['player', 'color', 'time', 'active']},
player: {type: 'string'}
team: {type: 'string'}
color: {type: 'string', enum: ['green', 'black', 'violet']}
time: {type: 'number', minimum: 0}
active: {type: 'boolean'}
pos: c.object {required: ['x', 'y']},
x: {type: 'number'}
y: {type: 'number'}
code:
type: 'object'

View file

@ -7,10 +7,12 @@ module.exports =
preload: {type: 'boolean'}
realTime: {type: 'boolean'}
'tome:cast-spells': c.object {title: 'Cast Spells', description: 'Published when spells are cast', required: ['spells', 'preload', 'realTime']},
'tome:cast-spells': c.object {title: 'Cast Spells', description: 'Published when spells are cast', required: ['spells', 'preload', 'realTime', 'submissionCount', 'flagHistory']},
spells: [type: 'object']
preload: [type: 'boolean']
realTime: [type: 'boolean']
submissionCount: [type: 'integer']
flagHistory: [type: 'array']
'tome:manual-cast': c.object {title: 'Manually Cast Spells', description: 'Published when you wish to manually recast all spells', required: []},
realTime: {type: 'boolean'}

View file

@ -157,11 +157,15 @@ module.exports = class TomeView extends CocoView
onCastSpell: (e) ->
# A single spell is cast.
# Hmm; do we need to make sure other spells are all cast here?
@cast e?.preload, e?.realTime
cast: (preload=false, realTime=false) ->
Backbone.Mediator.publish 'tome:cast-spells', spells: @spells, preload: preload, realTime: realTime
sessionState = @options.session.get('state') ? {}
if realTime
sessionState.submissionCount = (sessionState.submissionCount ? 0) + 1
sessionState.flagHistory = []
@options.session.set 'state', sessionState
Backbone.Mediator.publish 'tome:cast-spells', spells: @spells, preload: preload, realTime: realTime, submissionCount: sessionState.submissionCount ? 0, flagHistory: sessionState.flagHistory ? []
onToggleSpellList: (e) ->
@spellList.rerenderEntries()
@ -230,7 +234,7 @@ module.exports = class TomeView extends CocoView
reloadAllCode: ->
spell.view.reloadCode false for spellKey, spell of @spells when spell.view and (spell.team is me.team or (spell.team in ['common', 'neutral', null]))
Backbone.Mediator.publish 'tome:cast-spells', spells: @spells, preload: false, realTime: false
@cast false, false
updateLanguageForAllSpells: (e) ->
spell.updateLanguageAether e.language for spellKey, spell of @spells when spell.canWrite()

View file

@ -78,6 +78,8 @@ work = () ->
try
self.world = new World(args.userCodeMap)
self.world.levelSessionIDs = args.levelSessionIDs
self.world.submissionCount = args.submissionCount
self.world.flagHistory = args.flagHistory
self.world.loadFromLevel args.level, true if args.level
self.world.headless = args.headless
self.goalManager = new GoalManager(self.world)