Skip to content

Commit 68444f8

Browse files
author
Julien Poulton
committed
Merge branch 'master' into 'doc-sdk'
# Conflicts: # playground/misc/misc-3-release-notes.md
2 parents 0c36a95 + c108b8e commit 68444f8

File tree

11 files changed

+180
-91
lines changed

11 files changed

+180
-91
lines changed

engine/modules/entities/src/main/java/com/codingame/gameengine/module/entities/GraphicEntityModule.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,14 +200,12 @@ private void sendFrameData() {
200200
currentWorldState.updateAllEntities(nextWorldState);
201201
}
202202

203-
Optional<String> worldCommits = gameSerializer.serializeWorldCommits(worldCommitsBuilder);
204-
205203
Optional<String> update = gameSerializer.serializeWorldDiff(updateBuilder);
206204

207205
worldStates.clear();
208206
gameManager.setViewData(
209207
"entitymodule",
210-
Stream.of(load, create, update, worldCommits)
208+
Stream.of(load, create, update)
211209
.filter(Optional::isPresent)
212210
.map(Optional::get)
213211
.collect(Collectors.joining("\n"))

engine/modules/entities/src/main/java/com/codingame/gameengine/module/entities/Serializer.java

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ class Serializer {
7171
commands.put("CREATE", "C");
7272
commands.put("UPDATE", "U");
7373
commands.put("LOADSPRITESHEET", "L");
74-
commands.put("WORLDUPDATE", "W");
7574

7675
separators = new HashMap<>();
7776
separators.put("COMMAND", ";");
@@ -229,18 +228,6 @@ public Optional<String> serializeLoadSpriteSheets(List<SpriteSheetSplitter> spri
229228
}
230229
}
231230

232-
public Optional<String> serializeWorldCommits(List<String> worldCommits) {
233-
if (worldCommits.isEmpty()) {
234-
return Optional.empty();
235-
} else {
236-
return Optional.of(
237-
commands.get("WORLDUPDATE") +
238-
worldCommits.stream()
239-
.collect(Collectors.joining(separators.get("COMMAND_ARGUMENT")))
240-
);
241-
}
242-
}
243-
244231
public Optional<String> serializeWorldDiff(List<WorldState> diffs) {
245232
if (diffs.isEmpty()) {
246233
return Optional.empty();

engine/modules/entities/src/main/resources/view/entity-module/Command.js

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -152,18 +152,6 @@ export class PropertiesCommand {
152152
apply (entities, frameInfo) {
153153
let entity = entities.get(this.id)
154154
entity.addState(this.t, { values: this.params, curve: this.curve }, frameInfo.number, frameInfo)
155-
}
156-
}
157-
export class WorldCommitCommand {
158-
constructor (args, globalData) {
159-
this.times = args.map(v => +v)
160-
}
161-
162-
apply (entities, frameInfo) {
163-
entities.forEach(entity => {
164-
this.times.forEach(time => {
165-
entity.addState(time, { values: {}, curve: {} }, frameInfo.number, frameInfo)
166-
})
167-
})
155+
entity.stateAdded = true
168156
}
169157
}

engine/modules/entities/src/main/resources/view/entity-module/CommandParser.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import { CreateCommand, PropertiesCommand, LoadCommand, WorldCommitCommand } from './Command.js'
1+
import { CreateCommand, PropertiesCommand, LoadCommand } from './Command.js'
22

33
const COMMAND_KEY_MAP = {
44
C: CreateCommand,
55
U: PropertiesCommand,
6-
L: LoadCommand,
7-
W: WorldCommitCommand
6+
L: LoadCommand
87
}
98

109
function splitOnCharOutsideQuotes (text, charParam) {

engine/modules/entities/src/main/resources/view/entity-module/Entity.js

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -62,19 +62,31 @@ export class Entity {
6262
render (progress, data, globalData) {
6363
let subframes = this.states[data.number]
6464
this.container.visible = false
65+
let start = null
66+
let end
67+
// This t is used to animate the interpolation
68+
let t = 1
6569
if (subframes && subframes.length) {
6670
let index = 0
6771
while (index < subframes.length - 1 && subframes[index].t < progress) {
6872
index++
6973
}
70-
let start = subframes[index - 1]
71-
let end = subframes[index]
72-
// This t is used to animate the interpolation
73-
let t
74+
75+
start = subframes[index - 1]
76+
end = subframes[index]
7477

7578
if (!start) {
76-
// The start frame must be at the end of the previous turn
77-
var prev = this.states[data.previous.number] || []
79+
// The start frame must be at the end of a previous turn
80+
let frameNumbers = Object.keys(this.states)
81+
let index = frameNumbers.indexOf(data.number.toString()) - 1
82+
// Failsafe
83+
if (index === -1) {
84+
index = frameNumbers.length - 1
85+
}
86+
while (index >= 0 && frameNumbers[index] >= data.number) {
87+
index--
88+
}
89+
let prev = this.states[frameNumbers[index]] || []
7890
start = prev[prev.length - 1]
7991

8092
// If it didn't exist on the previous turn, don't even animate it
@@ -88,41 +100,53 @@ export class Entity {
88100
} else {
89101
t = unlerp(start.t, end.t, progress)
90102
}
91-
if (start) {
92-
const changed = {}
93-
const state = Object.assign({}, this.currentState)
94-
95-
for (let property of this.properties) {
96-
const opts = PROPERTIES[property] || PROPERTIES.default
97-
const lerpMethod = opts.lerpMethod
98-
const curve = end.curve[property] || (a => a)
99-
const newValue = lerpMethod(start[property], end[property], curve(t))
100-
if (newValue !== this.currentState[property]) {
101-
changed[property] = true
102-
state[property] = newValue
103-
}
104-
}
105-
this.updateDisplay(state, changed, globalData, data, progress)
106-
Object.assign(this.currentState, state)
107-
this.container.visible = this.container._visible
108-
if (changed.children) {
109-
globalData.mustResetTree = true
110-
if (typeof this.postUpdate === 'function') {
111-
globalData.updatedBuffers.push(this)
112-
}
113-
}
114-
if (changed.zIndex) {
115-
globalData.mustResort = true
116-
}
117-
if (changed.mask) {
118-
globalData.maskUpdates[this.id] = state.mask
103+
} else {
104+
// Look for the most recent state, but don't interpolate?
105+
let frameNumbers = Object.keys(this.states)
106+
let index = frameNumbers.length - 1
107+
while (index >= 0 && frameNumbers[index] > data.number) {
108+
index--
109+
}
110+
let substates = this.states[frameNumbers[index]]
111+
112+
if (substates != null) {
113+
start = substates[substates.length - 1]
114+
end = start
115+
} else {
116+
Object.assign(this.currentState, this.defaultState)
117+
}
118+
}
119+
if (start) {
120+
const changed = {}
121+
const state = Object.assign({}, this.currentState)
122+
for (let property of this.properties) {
123+
const opts = PROPERTIES[property] || PROPERTIES.default
124+
const lerpMethod = opts.lerpMethod
125+
const curve = end.curve[property] || (a => a)
126+
const newValue = lerpMethod(start[property], end[property], curve(t))
127+
if (newValue !== this.currentState[property]) {
128+
changed[property] = true
129+
state[property] = newValue
119130
}
120-
if (Object.keys(changed).length !== 0 && this.parent) {
121-
this.parent.notifyChange()
131+
}
132+
this.updateDisplay(state, changed, globalData, data, progress)
133+
Object.assign(this.currentState, state)
134+
this.container.visible = this.container._visible
135+
if (changed.children) {
136+
globalData.mustResetTree = true
137+
if (typeof this.postUpdate === 'function') {
138+
globalData.updatedBuffers.push(this)
122139
}
123140
}
124-
} else {
125-
Object.assign(this.currentState, this.defaultState)
141+
if (changed.zIndex) {
142+
globalData.mustResort = true
143+
}
144+
if (changed.mask) {
145+
globalData.maskUpdates[this.id] = state.mask
146+
}
147+
if (Object.keys(changed).length !== 0 && this.parent) {
148+
this.parent.notifyChange()
149+
}
126150
}
127151
}
128152

engine/modules/entities/src/main/resources/view/entity-module/GraphicEntityModule.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,13 @@ export class GraphicEntityModule {
7575
const previousFrameNumber = frameInfo.previous.number
7676
this
7777
.entities.forEach(entity => {
78+
// Only create if entity is affected by this frameInfo
79+
if (entity.stateAdded) {
80+
entity.stateAdded = false
81+
} else {
82+
return
83+
}
84+
7885
// Create empty substate array if none
7986
if (!entity.states[frameNumber]) {
8087
entity.states[frameNumber] = []

engine/modules/tooltip/src/main/resources/view/tooltip-module/TooltipModule.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,21 @@ function getMouseOutFunc (id, tooltip) {
1515
}
1616
}
1717

18+
function getEntityCurrentSubStates (entity, frame) {
19+
if (entity.states[frame]) {
20+
return entity.states[frame]
21+
}
22+
let frameNumbers = Object.keys(entity.states)
23+
let index = frameNumbers.length - 1
24+
25+
while (index >= 0 && frameNumbers[index] > frame) {
26+
index--
27+
}
28+
return entity.states[frameNumbers[index]] || []
29+
}
30+
1831
function getEntityState (entity, frame) {
19-
const subStates = entity.states[frame]
32+
const subStates = getEntityCurrentSubStates(entity, frame)
2033
if (subStates && subStates.length) {
2134
return subStates[subStates.length - 1]
2235
}

playground/misc/misc-3-release-notes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ The CodinGame SDK is regularly updated and improved. This document lets you know
1010
- `Fixed missing line breaks in the Game Summary console`
1111
- `Better error reporting on player agent crash`
1212
- `Multiple commands can now be launched with CommandLinePlayerAgent`
13+
- `Games now require less RAM in the CodinGame IDE`
1314

1415
## 3.4.8
1516

runner/src/main/java/com/codingame/gameengine/runner/CommandLinePlayerAgent.java

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,29 @@ public class CommandLinePlayerAgent extends Agent {
1313
private OutputStream processStdin;
1414
private InputStream processStdout;
1515
private InputStream processStderr;
16-
private String commandLine;
16+
private String[] commandArray;
1717
private Process process;
1818

1919
/**
2020
* Creates an Agent for your game, will run the given commandLine at game start
2121
*
2222
* @param commandLine
23-
* the commandLine to run
23+
* the command line to run
2424
*/
2525
public CommandLinePlayerAgent(String commandLine) {
2626
super();
27-
try {
28-
this.commandLine = commandLine;
29-
} catch (Exception e) {
30-
}
27+
this.commandArray = commandLine.split(" ");
28+
}
29+
30+
/**
31+
* Creates an Agent for your game, will run the given commandLine at game start
32+
*
33+
* @param commandArray
34+
* the command array to run
35+
*/
36+
public CommandLinePlayerAgent(String[] commandArray) {
37+
super();
38+
this.commandArray = commandArray;
3139
}
3240

3341
@Override
@@ -47,11 +55,10 @@ protected InputStream getErrorStream() {
4755

4856
@Override
4957
public void initialize(Properties conf) {
50-
5158
try {
52-
this.process = Runtime.getRuntime().exec(commandLine);
59+
this.process = Runtime.getRuntime().exec(commandArray);
5360
} catch (IOException e) {
54-
throw new RuntimeException("Failed to launch " + commandLine, e);
61+
throw new RuntimeException("Failed to launch " + String.join(" ", commandArray));
5562
}
5663
processStdin = process.getOutputStream();
5764
processStdout = process.getInputStream();

runner/src/main/java/com/codingame/gameengine/runner/GameRunner.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,22 @@ private String getNextPlayerOutput(NextPlayerInfo nextPlayerInfo, String nextPla
270270
String playerOutput = player.getOutput(nextPlayerInfo.nbLinesNextOutput, nextPlayerInfo.timeout);
271271
if (playerOutput != null)
272272
playerOutput = playerOutput.replace('\r', '\n');
273-
readError(player);
274273

275-
if (checkOutput(playerOutput, nextPlayerInfo.nbLinesNextOutput) != OutputResult.OK) {
274+
if (checkOutput(playerOutput, nextPlayerInfo.nbLinesNextOutput) == OutputResult.OK) {
275+
// Read this turn's stderr
276+
readError(player);
277+
} else {
278+
// Give the agent time to crash cleanly
279+
try {
280+
Thread.sleep(nextPlayerInfo.timeout);
281+
} catch (InterruptedException e) {
282+
e.printStackTrace();
283+
}
284+
// Read this turns stderr and the crash output
285+
readError(player);
276286
return null;
277287
}
288+
278289
if ((playerOutput != null) && playerOutput.isEmpty() && (nextPlayerInfo.nbLinesNextOutput == 1)) {
279290
return "\n";
280291
}

0 commit comments

Comments
 (0)