Skip to content

Commit c3e28db

Browse files
committed
Craftax + classic port up to 5
1 parent 72b734e commit c3e28db

5 files changed

Lines changed: 184 additions & 213 deletions

File tree

ocean/craftax/binding.c

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,14 @@
1515
#define MY_VEC_STEP craftax_vec_step
1616
#define MY_VEC_STEP_RANGE craftax_vec_step_range
1717
#define Env Craftax
18+
static inline void puffer_state_refresh(Craftax* env) {
19+
craftax_encode_native_observation(&env->state, env->observations);
20+
}
1821
#include "vecenv.h"
1922

2023
// Tiled vector step: process agents in tiles that fit comfortably in cache.
21-
// Each thread processes a contiguous block of lightweight env handles while
22-
// the heavier CraftaxState storage lives in a separate arena.
24+
// Each thread processes a contiguous block of env handles and their embedded
25+
// Puffer 5 State payloads.
2326
void craftax_vec_step(StaticVec* vec) {
2427
memset(vec->rewards, 0, vec->total_agents * sizeof(float));
2528
memset(vec->terminals, 0, vec->total_agents * sizeof(float));
@@ -50,10 +53,6 @@ void craftax_vec_step_range(StaticVec* vec, int env_start, int env_count, int nu
5053
}
5154
}
5255

53-
static CraftaxState* craftax_alloc_state_arena(int num_envs) {
54-
return (CraftaxState*)calloc((size_t)num_envs, sizeof(CraftaxState));
55-
}
56-
5756
Env* my_vec_init(
5857
int* num_envs_out,
5958
int* buffer_env_starts,
@@ -67,12 +66,6 @@ Env* my_vec_init(
6766
int num_envs = total_agents;
6867

6968
Env* envs = (Env*)calloc((size_t)num_envs, sizeof(Env));
70-
CraftaxArena* arena = (CraftaxArena*)calloc(1, sizeof(CraftaxArena));
71-
arena->states = craftax_alloc_state_arena(num_envs);
72-
arena->num_envs = num_envs;
73-
arena->packet_size = CRAFTAX_ARENA_PACKET_SIZE;
74-
arena->num_packets = (num_envs + CRAFTAX_ARENA_PACKET_SIZE - 1)
75-
/ CRAFTAX_ARENA_PACKET_SIZE;
7669

7770
int buf = 0;
7871
int buf_agents = 0;
@@ -82,11 +75,6 @@ Env* my_vec_init(
8275
for (int i = 0; i < num_envs; i++) {
8376
Env* env = &envs[i];
8477
env->rng = (unsigned int)i;
85-
env->arena = arena;
86-
env->state = &arena->states[i];
87-
env->packet_id = i / arena->packet_size;
88-
env->lane_id = i % arena->packet_size;
89-
env->owns_state_storage = false;
9078
my_init(env, env_kwargs);
9179

9280
buf_agents += env->num_agents;
@@ -104,13 +92,7 @@ Env* my_vec_init(
10492
}
10593

10694
void my_vec_close(Env* envs) {
107-
if (envs == NULL || envs[0].arena == NULL) {
108-
return;
109-
}
110-
111-
CraftaxArena* arena = envs[0].arena;
112-
free(arena->states);
113-
free(arena);
95+
(void)envs;
11496
}
11597

11698
void my_init(Env* env, Dict* kwargs) {

ocean/craftax/craftax.h

Lines changed: 20 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ typedef struct CraftaxMobs2 {
345345
int32_t type_id[CRAFTAX_NUM_LEVELS][2];
346346
} CraftaxMobs2;
347347

348-
typedef struct CraftaxState {
348+
typedef struct State {
349349
// === Hot data (accessed every step) ===
350350
int32_t player_position[2];
351351
int32_t player_level;
@@ -416,7 +416,9 @@ typedef struct CraftaxState {
416416
int32_t up_ladders[CRAFTAX_NUM_LEVELS][2];
417417
bool chests_opened[CRAFTAX_NUM_LEVELS];
418418
int32_t monsters_killed[CRAFTAX_NUM_LEVELS];
419-
} CraftaxState;
419+
} State;
420+
421+
typedef State CraftaxState;
420422

421423
typedef char CraftaxStateMatchesWorldState[
422424
(sizeof(CraftaxState) == sizeof(CraftaxWorldState)) ? 1 : -1
@@ -494,15 +496,6 @@ static inline void craftax_refresh_spawn_bits_all(CraftaxState* state) {
494496
}
495497
}
496498

497-
#define CRAFTAX_ARENA_PACKET_SIZE 64
498-
499-
typedef struct CraftaxArena {
500-
CraftaxState* states;
501-
int num_envs;
502-
int packet_size;
503-
int num_packets;
504-
} CraftaxArena;
505-
506499
#ifdef CRAFTAX_ENABLE_ENV_IMPL
507500
static inline void craftax_change_floor_native(CraftaxState* state, int32_t action);
508501
static inline void craftax_do_crafting_native(CraftaxState* state, int32_t action);
@@ -587,11 +580,7 @@ typedef struct Craftax {
587580
unsigned int rng;
588581
uint64_t seed;
589582
CraftaxThreefryKey rng_key;
590-
CraftaxArena* arena;
591-
CraftaxState* state;
592-
int32_t packet_id;
593-
int32_t lane_id;
594-
bool owns_state_storage;
583+
State state;
595584

596585
float achievements[CRAFTAX_NUM_ACHIEVEMENTS];
597586
float episode_return_accum;
@@ -678,37 +667,18 @@ static inline void craftax_set_reset_pool_size(int n) {
678667
g_craftax_reset_pool_ready = 1;
679668
}
680669

681-
static inline void craftax_ensure_state_storage(Craftax* env) {
682-
if (env->state != NULL) {
683-
return;
684-
}
685-
686-
CraftaxArena* arena = (CraftaxArena*)calloc(1, sizeof(CraftaxArena));
687-
arena->states = (CraftaxState*)calloc(1, sizeof(CraftaxState));
688-
arena->num_envs = 1;
689-
arena->packet_size = 1;
690-
arena->num_packets = 1;
691-
692-
env->arena = arena;
693-
env->state = arena->states;
694-
env->packet_id = 0;
695-
env->lane_id = 0;
696-
env->owns_state_storage = true;
697-
}
698-
699670
static inline void craftax_reset_state_from_seed(Craftax* env) {
700-
craftax_ensure_state_storage(env);
701671
CraftaxThreefryKey initial_key = craftax_prng_key((uint32_t)env->seed);
702672
if (g_craftax_reset_pool_size > 0) {
703673
CraftaxThreefryKey discard;
704674
craftax_threefry_split(initial_key, &env->rng_key, &discard);
705675
int idx = (int)(env->seed % (uint64_t)g_craftax_reset_pool_size);
706-
memcpy(env->state, &g_craftax_reset_pool[idx], sizeof(CraftaxState));
676+
memcpy(&env->state, &g_craftax_reset_pool[idx], sizeof(CraftaxState));
707677
return;
708678
}
709679
CraftaxThreefryKey reset_key;
710680
craftax_threefry_split(initial_key, &env->rng_key, &reset_key);
711-
craftax_reset_state_from_reset_key(env->state, reset_key);
681+
craftax_reset_state_from_reset_key(&env->state, reset_key);
712682
}
713683

714684
// Hot-path reset used by c_step on episode-done. Consults the reset pool
@@ -865,7 +835,6 @@ static float craftax_gameplay_step_native(
865835
static void c_init(Craftax* env) {
866836
env->client = NULL;
867837
env->num_agents = 1;
868-
craftax_ensure_state_storage(env);
869838
env->episode_return_accum = 0.0f;
870839
env->episode_length_accum = 0;
871840
memset(env->achievements, 0, sizeof(env->achievements));
@@ -886,7 +855,7 @@ static void c_reset(Craftax* env) {
886855
memset(env->achievements, 0, sizeof(env->achievements));
887856

888857
craftax_reset_state_from_seed(env);
889-
craftax_encode_native_observation(env->state, env->observations);
858+
craftax_encode_native_observation(&env->state, env->observations);
890859
}
891860

892861
#ifdef CRAFTAX_PROFILE
@@ -912,14 +881,14 @@ static void c_step_native(Craftax* env) {
912881
craftax_threefry_split(step_key, &step_rng, &reset_key);
913882
CRAFTAX_PROFILE_END(12);
914883

915-
float reward = craftax_gameplay_step_native(env->state, action, step_rng);
884+
float reward = craftax_gameplay_step_native(&env->state, action, step_rng);
916885

917886
CRAFTAX_PROFILE_ZONE(13);
918-
bool done = craftax_is_game_over_native(env->state);
887+
bool done = craftax_is_game_over_native(&env->state);
919888
CRAFTAX_PROFILE_END(13);
920889

921890
CRAFTAX_PROFILE_ZONE(15);
922-
craftax_copy_achievements_to_env(env, env->state);
891+
craftax_copy_achievements_to_env(env, &env->state);
923892
CRAFTAX_PROFILE_END(15);
924893

925894
CRAFTAX_PROFILE_ZONE(16);
@@ -935,12 +904,12 @@ static void c_step_native(Craftax* env) {
935904
env->episode_length_accum = 0;
936905
memset(env->achievements, 0, sizeof(env->achievements));
937906
CRAFTAX_PROFILE_ZONE(14);
938-
craftax_reset_state_on_done(env->state, reset_key);
907+
craftax_reset_state_on_done(&env->state, reset_key);
939908
CRAFTAX_PROFILE_END(14);
940909
}
941910

942911
CRAFTAX_PROFILE_ZONE(11);
943-
craftax_encode_native_observation(env->state, env->observations);
912+
craftax_encode_native_observation(&env->state, env->observations);
944913
CRAFTAX_PROFILE_END(11);
945914

946915
// Record unprofiled time
@@ -974,9 +943,9 @@ static void c_step_gameplay(Craftax* env) {
974943
CraftaxThreefryKey reset_key;
975944
craftax_threefry_split(step_key, &step_rng, &reset_key);
976945

977-
float reward = craftax_gameplay_step_native(env->state, action, step_rng);
978-
bool done = craftax_is_game_over_native(env->state);
979-
craftax_copy_achievements_to_env(env, env->state);
946+
float reward = craftax_gameplay_step_native(&env->state, action, step_rng);
947+
bool done = craftax_is_game_over_native(&env->state);
948+
craftax_copy_achievements_to_env(env, &env->state);
980949

981950
env->rewards[0] = reward;
982951
env->terminals[0] = done ? 1.0f : 0.0f;
@@ -988,12 +957,12 @@ static void c_step_gameplay(Craftax* env) {
988957
env->episode_return_accum = 0.0f;
989958
env->episode_length_accum = 0;
990959
memset(env->achievements, 0, sizeof(env->achievements));
991-
craftax_reset_state_on_done(env->state, reset_key);
960+
craftax_reset_state_on_done(&env->state, reset_key);
992961
}
993962
}
994963

995964
static void c_step_encode(Craftax* env) {
996-
craftax_encode_native_observation(env->state, env->observations);
965+
craftax_encode_native_observation(&env->state, env->observations);
997966
}
998967

999968
static void c_step(Craftax* env) {
@@ -1002,14 +971,7 @@ static void c_step(Craftax* env) {
1002971
}
1003972

1004973
static void c_close(Craftax* env) {
1005-
if (!env->owns_state_storage || env->arena == NULL) {
1006-
return;
1007-
}
1008-
free(env->arena->states);
1009-
free(env->arena);
1010-
env->arena = NULL;
1011-
env->state = NULL;
1012-
env->owns_state_storage = false;
974+
(void)env;
1013975
}
1014976

1015977
// ------------------------------------------------------------
@@ -1108,7 +1070,7 @@ static void c_render(Craftax* env) {
11081070
if (!craftax_textures_loaded) craftax_load_textures();
11091071
if (IsKeyDown(KEY_ESCAPE)) exit(0);
11101072

1111-
CraftaxState* s = env->state;
1073+
State* s = &env->state;
11121074
int lvl = s->player_level;
11131075
int pr = s->player_position[0];
11141076
int pc = s->player_position[1];

ocean/craftax/step_spawn_mobs.h

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,30 @@ static int32_t craftax_spawn_hostile_span_count = 0;
3838
static int32_t craftax_spawn_boss_span_count = 0;
3939
static int32_t craftax_spawn_offsets_initialized = 0;
4040

41+
static const uint8_t CRAFTAX_SPAWN_ALL_VALID_BLOCK_FLAGS[CRAFTAX_NUM_BLOCK_TYPES] = {
42+
0, 0, 1, 0, 0, 0, 0, 1,
43+
0, 0, 0, 0, 0, 0, 0, 0,
44+
0, 0, 0, 0, 0, 0, 0, 0,
45+
0, 1, 1, 0, 0, 0, 0, 0,
46+
0, 0, 0, 0, 0,
47+
};
48+
49+
static const uint8_t CRAFTAX_SPAWN_GRAVE_BLOCK_FLAGS[CRAFTAX_NUM_BLOCK_TYPES] = {
50+
0, 0, 0, 0, 0, 0, 0, 0,
51+
0, 0, 0, 0, 0, 0, 0, 0,
52+
0, 0, 0, 0, 0, 0, 0, 0,
53+
0, 0, 0, 0, 0, 0, 0, 0,
54+
0, 1, 1, 1, 0,
55+
};
56+
57+
static const uint8_t CRAFTAX_SPAWN_WATER_BLOCK_FLAGS[CRAFTAX_NUM_BLOCK_TYPES] = {
58+
0, 0, 0, 1, 0, 0, 0, 0,
59+
0, 0, 0, 0, 0, 0, 0, 0,
60+
0, 0, 0, 0, 0, 0, 0, 0,
61+
0, 0, 0, 0, 0, 0, 0, 0,
62+
0, 0, 0, 0, 0,
63+
};
64+
4165
static inline void craftax_spawn_append_span(
4266
CraftaxSpawnOffsetSpan* spans,
4367
int32_t* count,
@@ -208,32 +232,18 @@ static inline float craftax_spawn_mob_type_health(
208232
}
209233

210234
static inline bool craftax_spawn_is_all_valid_block(int32_t block) {
211-
static const uint8_t flags[CRAFTAX_NUM_BLOCK_TYPES] = {
212-
[CRAFTAX_BLOCK_GRASS] = 1,
213-
[CRAFTAX_BLOCK_PATH] = 1,
214-
[CRAFTAX_BLOCK_FIRE_GRASS] = 1,
215-
[CRAFTAX_BLOCK_ICE_GRASS] = 1,
216-
};
217235
int32_t idx = craftax_step_jax_index(block, CRAFTAX_NUM_BLOCK_TYPES);
218-
return flags[idx] != 0;
236+
return CRAFTAX_SPAWN_ALL_VALID_BLOCK_FLAGS[idx] != 0;
219237
}
220238

221239
static inline bool craftax_spawn_is_grave_block(int32_t block) {
222-
static const uint8_t flags[CRAFTAX_NUM_BLOCK_TYPES] = {
223-
[CRAFTAX_BLOCK_GRAVE] = 1,
224-
[CRAFTAX_BLOCK_GRAVE2] = 1,
225-
[CRAFTAX_BLOCK_GRAVE3] = 1,
226-
};
227240
int32_t idx = craftax_step_jax_index(block, CRAFTAX_NUM_BLOCK_TYPES);
228-
return flags[idx] != 0;
241+
return CRAFTAX_SPAWN_GRAVE_BLOCK_FLAGS[idx] != 0;
229242
}
230243

231244
static inline bool craftax_spawn_is_water_block(int32_t block) {
232-
static const uint8_t flags[CRAFTAX_NUM_BLOCK_TYPES] = {
233-
[CRAFTAX_BLOCK_WATER] = 1,
234-
};
235245
int32_t idx = craftax_step_jax_index(block, CRAFTAX_NUM_BLOCK_TYPES);
236-
return flags[idx] != 0;
246+
return CRAFTAX_SPAWN_WATER_BLOCK_FLAGS[idx] != 0;
237247
}
238248

239249
static inline int32_t craftax_spawn_player_distance_squared(

ocean/craftax_classic/binding.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
#define OBS_TENSOR_T FloatTensor
77

88
#define Env CraftaxClassic
9+
static inline void puffer_state_refresh(CraftaxClassic* env) {
10+
compute_observations(&env->state, env->observations);
11+
}
912
#include "vecenv.h"
1013

1114
void my_init(Env* env, Dict* kwargs) {

0 commit comments

Comments
 (0)